| /**************************************************************************** |
| ** |
| ** Copyright (C) 2016 The Qt Company Ltd. |
| ** Contact: https://www.qt.io/licensing/ |
| ** |
| ** This file is part of the test suite of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include <QIdentityProxyModel> |
| #include <QLabel> |
| #include <QLineEdit> |
| #include <QScrollBar> |
| #include <QSignalSpy> |
| #include <QSortFilterProxyModel> |
| #include <QStandardItemModel> |
| #include <QStringListModel> |
| #include <QStyledItemDelegate> |
| #include <QTableView> |
| #include <QTest> |
| #include <private/qapplication_p.h> |
| #include <private/qtablewidget_p.h> |
| #include <private/qtesthelpers_p.h> |
| #if QT_CONFIG(textmarkdownwriter) |
| #include <private/qtextmarkdownwriter_p.h> |
| #endif |
| |
| |
| using namespace QTestPrivate; |
| |
| #ifdef QT_BUILD_INTERNAL |
| #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \ |
| QVERIFY(static_cast<QTableViewPrivate*>(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency()) |
| #else |
| #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) (void)false |
| #endif |
| |
| Q_DECLARE_METATYPE(Qt::Key); |
| Q_DECLARE_METATYPE(Qt::KeyboardModifier); |
| Q_DECLARE_METATYPE(QItemSelectionModel::SelectionFlag); |
| using BoolList = QVector<bool>; |
| using IntList = QVector<int>; |
| using KeyList = QVector<Qt::Key>; |
| using SpanList = QVector<QRect>; |
| |
| class QtTestTableModel: public QAbstractTableModel |
| { |
| Q_OBJECT |
| |
| signals: |
| void invalidIndexEncountered() const; |
| |
| public slots: |
| bool submit() override { ++submit_count; return QAbstractTableModel::submit(); } |
| |
| public: |
| QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = nullptr) |
| : QAbstractTableModel(parent), row_count(rows), column_count(columns) |
| {} |
| |
| int rowCount(const QModelIndex& = QModelIndex()) const override |
| { |
| return row_count; |
| } |
| |
| int columnCount(const QModelIndex& = QModelIndex()) const override |
| { |
| return column_count; |
| } |
| |
| bool isEditable(const QModelIndex &) const { return true; } |
| |
| Qt::ItemFlags flags(const QModelIndex &index) const override |
| { |
| 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 = Qt::DisplayRole) const override |
| { |
| 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 QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',') |
| + QString::number(idx.column()) + QLatin1String(",0]"); |
| } |
| |
| return QVariant(); |
| } |
| |
| bool insertRows(int start, int count, const QModelIndex &parent = QModelIndex()) override |
| { |
| 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()) override |
| { |
| 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()) override |
| { |
| 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()) override |
| { |
| 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 override |
| { |
| return can_fetch_more; |
| } |
| |
| void fetchMore(const QModelIndex &) override |
| { |
| ++fetch_more_count; |
| } |
| |
| QSet<int> disabled_rows; |
| QSet<int> disabled_columns; |
| int row_count; |
| int column_count; |
| int submit_count = 0; |
| int fetch_more_count = 0; |
| bool can_fetch_more = false; |
| }; |
| |
| class QtTestTableView : public QTableView |
| { |
| Q_OBJECT |
| public: |
| using QTableView::QTableView; |
| |
| void setModel(QAbstractItemModel *model) override |
| { |
| QTableView::setModel(model); |
| connect(selectionModel(), &QItemSelectionModel::currentChanged, |
| this, &QtTestTableView::slotCurrentChanged); |
| connect(selectionModel(), &QItemSelectionModel::selectionChanged, |
| this, &QtTestTableView::itemSelectionChanged); |
| // Allow small sections in this test, since this test was made before we correctly enforced minimum sizes. |
| horizontalHeader()->setMinimumSectionSize(0); |
| verticalHeader()->setMinimumSectionSize(0); |
| } |
| |
| using QTableView::moveCursor; |
| using QTableView::isIndexHidden; |
| using QTableView::setSelection; |
| using QTableView::selectedIndexes; |
| using QTableView::sizeHintForRow; |
| using QTableView::viewOptions; |
| |
| bool checkSignalOrder = false; |
| public slots: |
| void slotCurrentChanged(QModelIndex, QModelIndex) { |
| hasCurrentChanged++; |
| if (checkSignalOrder) |
| QVERIFY(hasCurrentChanged > hasSelectionChanged); |
| } |
| |
| void itemSelectionChanged(QItemSelection , QItemSelection ) { |
| hasSelectionChanged++; |
| if (checkSignalOrder) |
| QVERIFY(hasCurrentChanged >= hasSelectionChanged); |
| } |
| private: |
| int hasCurrentChanged = 0; |
| int hasSelectionChanged = 0; |
| |
| friend class tst_QTableView; |
| friend struct QMetaTypeId<QtTestTableView::CursorAction>; |
| }; |
| Q_DECLARE_METATYPE(QtTestTableView::CursorAction); |
| |
| class QtTestItemDelegate : public QStyledItemDelegate |
| { |
| public: |
| QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const override |
| { |
| return hint; |
| } |
| |
| QSize hint; |
| }; |
| |
| class tst_QTableView : public QObject |
| { |
| Q_OBJECT |
| |
| private: |
| using CursorActionList = QVector<QtTestTableView::CursorAction>; |
| private slots: |
| void getSetCheck(); |
| |
| void noDelegate(); |
| void noModel(); |
| void emptyModel(); |
| |
| void removeRows_data(); |
| void removeRows(); |
| |
| void removeColumns_data(); |
| void removeColumns(); |
| |
| void keyboardNavigation_data(); |
| void keyboardNavigation(); |
| |
| void headerSections_data(); |
| void headerSections(); |
| |
| void moveCursor_data(); |
| void moveCursor(); |
| |
| void moveCursorStrikesBack_data(); |
| void moveCursorStrikesBack(); |
| |
| void moveCursorBiggerJump(); |
| |
| void hideRows_data(); |
| void hideRows(); |
| |
| void hideColumns_data(); |
| void hideColumns(); |
| |
| void selection_data(); |
| void selection(); |
| |
| void selectRow_data(); |
| void selectRow(); |
| |
| void selectColumn_data(); |
| void selectColumn(); |
| |
| void selectall_data(); |
| void selectall(); |
| |
| 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 editSpanFromDirections_data(); |
| void editSpanFromDirections(); |
| |
| void checkHeaderReset(); |
| void checkHeaderMinSize(); |
| |
| void resizeToContents(); |
| |
| void tabFocus(); |
| void bigModel(); |
| void selectionSignal(); |
| void setCurrentIndex(); |
| |
| // task-specific tests: |
| void task173773_updateVerticalHeader(); |
| void task227953_setRootIndex(); |
| void task240266_veryBigColumn(); |
| void task248688_autoScrollNavigation(); |
| void task259308_scrollVerticalHeaderSwappedSections(); |
| void task191545_dragSelectRows(); |
| void taskQTBUG_5062_spansInconsistency(); |
| void taskQTBUG_4516_clickOnRichTextLabel(); |
| #if QT_CONFIG(wheelevent) |
| void taskQTBUG_5237_wheelEventOnHeader(); |
| #endif |
| void taskQTBUG_8585_crashForNoGoodReason(); |
| void taskQTBUG_7774_RtoLVisualRegionForSelection(); |
| void taskQTBUG_8777_scrollToSpans(); |
| void taskQTBUG_10169_sizeHintForRow(); |
| void taskQTBUG_30653_doItemsLayout(); |
| void taskQTBUG_50171_selectRowAfterSwapColumns(); |
| void deselectRow(); |
| |
| #if QT_CONFIG(wheelevent) |
| void mouseWheel_data(); |
| void mouseWheel(); |
| #endif |
| |
| void addColumnWhileEditing(); |
| void task234926_setHeaderSorting(); |
| |
| void changeHeaderData(); |
| void viewOptions(); |
| |
| void taskQTBUG_7232_AllowUserToControlSingleStep(); |
| |
| #if QT_CONFIG(textmarkdownwriter) |
| void markdownWriter(); |
| #endif |
| }; |
| |
| // 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(nullptr); |
| QCOMPARE(var1, obj1.horizontalHeader()); |
| delete var1; |
| |
| QHeaderView *var2 = new QHeaderView(Qt::Vertical); |
| obj1.setVerticalHeader(var2); |
| QCOMPARE(var2, obj1.verticalHeader()); |
| obj1.setVerticalHeader(nullptr); |
| QCOMPARE(var2, obj1.verticalHeader()); |
| delete var2; |
| |
| QCOMPARE(obj1.isCornerButtonEnabled(), true); |
| obj1.setCornerButtonEnabled(false); |
| QCOMPARE(obj1.isCornerButtonEnabled(), false); |
| } |
| void tst_QTableView::noDelegate() |
| { |
| QtTestTableModel model(3, 3); |
| QTableView view; |
| view.setModel(&model); |
| view.setItemDelegate(nullptr); |
| view.show(); |
| } |
| |
| void tst_QTableView::noModel() |
| { |
| QTableView view; |
| view.show(); |
| } |
| |
| void tst_QTableView::emptyModel() |
| { |
| QtTestTableModel model; |
| QTableView view; |
| QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered); |
| view.setModel(&model); |
| view.show(); |
| QCOMPARE(spy.count(), 0); |
| } |
| |
| void tst_QTableView::removeRows_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| |
| QTest::newRow("2x2") << 2 << 2; |
| QTest::newRow("10x10") << 10 << 10; |
| } |
| |
| void tst_QTableView::removeRows() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered); |
| |
| QTableView view; |
| view.setModel(&model); |
| view.show(); |
| |
| model.removeLastRow(); |
| QCOMPARE(spy.count(), 0); |
| |
| model.removeAllRows(); |
| QCOMPARE(spy.count(), 0); |
| } |
| |
| void tst_QTableView::removeColumns_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| |
| QTest::newRow("2x2") << 2 << 2; |
| QTest::newRow("10x10") << 10 << 10; |
| } |
| |
| void tst_QTableView::removeColumns() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered); |
| |
| QTableView view; |
| view.setModel(&model); |
| view.show(); |
| |
| model.removeLastColumn(); |
| QCOMPARE(spy.count(), 0); |
| |
| model.removeAllColumns(); |
| QCOMPARE(spy.count(), 0); |
| } |
| |
| void tst_QTableView::keyboardNavigation_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<bool>("tabKeyNavigation"); |
| QTest::addColumn<KeyList>("keyPresses"); |
| |
| const KeyList keyList { |
| 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("16x16 model") << 16 << 16 << true << keyList; |
| QTest::newRow("no tab") << 8 << 8 << false << keyList; |
| } |
| |
| void tst_QTableView::keyboardNavigation() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(bool, tabKeyNavigation); |
| QFETCH(const KeyList, 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(); |
| QApplication::setActiveWindow(&view); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| |
| int row = rowCount - 1; |
| int column = columnCount - 1; |
| for (Qt::Key key : keyPresses) { |
| |
| 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; |
| Q_FALLTHROUGH(); |
| case Qt::Key_Left: |
| column = qMax(0, column - 1); |
| break; |
| case Qt::Key_Tab: |
| if (!tabKeyNavigation) |
| break; |
| Q_FALLTHROUGH(); |
| case Qt::Key_Right: |
| column = qMin(columnCount - 1, column + 1); |
| break; |
| default: |
| break; |
| } |
| |
| QTest::keyClick(&view, key); |
| QApplication::processEvents(); |
| |
| QModelIndex index = model.index(row, column); |
| QCOMPARE(view.currentIndex(), index); |
| } |
| } |
| |
| void tst_QTableView::headerSections_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| |
| QTest::newRow("") << 10 << 10 << 5 << 5 << 30 << 30; |
| } |
| |
| void tst_QTableView::headerSections() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowHeight); |
| QFETCH(int, columnWidth); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| |
| QTableView view; |
| QHeaderView *hheader = view.horizontalHeader(); |
| QHeaderView *vheader = view.verticalHeader(); |
| |
| view.setModel(&model); |
| hheader->setMinimumSectionSize(columnWidth); |
| vheader->setMinimumSectionSize(rowHeight); |
| view.show(); |
| |
| hheader->doItemsLayout(); |
| vheader->doItemsLayout(); |
| |
| QCOMPARE(hheader->count(), model.columnCount()); |
| QCOMPARE(vheader->count(), model.rowCount()); |
| |
| view.setRowHeight(row, rowHeight); |
| QCOMPARE(view.rowHeight(row), rowHeight); |
| view.hideRow(row); |
| QCOMPARE(view.rowHeight(row), 0); |
| view.showRow(row); |
| QCOMPARE(view.rowHeight(row), rowHeight); |
| |
| view.setColumnWidth(column, columnWidth); |
| QCOMPARE(view.columnWidth(column), columnWidth); |
| view.hideColumn(column); |
| QCOMPARE(view.columnWidth(column), 0); |
| view.showColumn(column); |
| QCOMPARE(view.columnWidth(column), columnWidth); |
| } |
| |
| typedef QPair<int,int> IntPair; |
| |
| void tst_QTableView::moveCursor_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("hideRow"); |
| QTest::addColumn<int>("hideColumn"); |
| |
| QTest::addColumn<int>("startRow"); |
| QTest::addColumn<int>("startColumn"); |
| |
| QTest::addColumn<QtTestTableView::CursorAction>("cursorMoveAction"); |
| QTest::addColumn<Qt::KeyboardModifier>("modifier"); |
| |
| QTest::addColumn<int>("expectedRow"); |
| QTest::addColumn<int>("expectedColumn"); |
| QTest::addColumn<IntPair>("moveRow"); |
| QTest::addColumn<IntPair>("moveColumn"); |
| |
| // MoveRight |
| QTest::newRow("MoveRight (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveRight << Qt::NoModifier |
| << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveRight (3,0)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 0 |
| << QtTestTableView::MoveRight << Qt::NoModifier |
| << 3 << 1 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveRight (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveRight << Qt::NoModifier |
| << 3 << 3 << IntPair(0,0) << IntPair(0,0); // ### |
| |
| QTest::newRow("MoveRight, hidden column 1 (0,0)") |
| << 4 << 4 << -1 << 1 |
| << 0 << 0 |
| << QtTestTableView::MoveRight << Qt::NoModifier |
| << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveRight, hidden column 3 (0,2)") |
| << 4 << 4 << -1 << 3 |
| << 0 << 2 |
| << QtTestTableView::MoveRight << 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 |
| << QtTestTableView::MoveNext << Qt::NoModifier |
| << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveNext (0,2)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 2 |
| << QtTestTableView::MoveNext << Qt::NoModifier |
| << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveNext, wrap (0,3)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 3 |
| << QtTestTableView::MoveNext << Qt::NoModifier |
| << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveNext, wrap (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveNext << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveNext, hidden column 1 (0,0)") |
| << 4 << 4 << -1 << 1 |
| << 0 << 0 |
| << QtTestTableView::MoveNext << 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 |
| << QtTestTableView::MoveNext << 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 |
| << QtTestTableView::MoveNext << 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 |
| << QtTestTableView::MoveNext << 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 |
| << QtTestTableView::MoveNext << Qt::NoModifier |
| << 1 << 3 << IntPair(0,0) << IntPair(3,0); |
| |
| // MoveLeft |
| QTest::newRow("MoveLeft (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveLeft << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveLeft (0,3)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 3 |
| << QtTestTableView::MoveLeft << Qt::NoModifier |
| << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveLeft (1,0)") |
| << 4 << 4 << -1 << -1 |
| << 1 << 0 |
| << QtTestTableView::MoveLeft << Qt::NoModifier |
| << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveLeft, hidden column 0 (0,2)") |
| << 4 << 4 << -1 << 1 |
| << 0 << 2 |
| << QtTestTableView::MoveLeft << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveLeft, hidden column 0 (0,1)") |
| << 4 << 4 << -1 << 0 |
| << 0 << 1 |
| << QtTestTableView::MoveLeft << 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 |
| << QtTestTableView::MovePrevious << Qt::NoModifier |
| << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePrevious (0,1)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 1 |
| << QtTestTableView::MovePrevious << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePrevious, wrap (1,0)") |
| << 4 << 4 << -1 << -1 |
| << 1 << 0 |
| << QtTestTableView::MovePrevious << Qt::NoModifier |
| << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePrevious, wrap, (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MovePrevious << Qt::NoModifier |
| << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePrevious, hidden column 1 (0,2)") |
| << 4 << 4 << -1 << 1 |
| << 0 << 2 |
| << QtTestTableView::MovePrevious << 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 |
| << QtTestTableView::MovePrevious << 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 |
| << QtTestTableView::MovePrevious << 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 |
| << QtTestTableView::MovePrevious << 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 |
| << QtTestTableView::MovePrevious << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,3); |
| |
| // MoveDown |
| QTest::newRow("MoveDown (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveDown << Qt::NoModifier |
| << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveDown (3,0)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 0 |
| << QtTestTableView::MoveDown << Qt::NoModifier |
| << 3 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveDown (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveDown << Qt::NoModifier |
| << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveDown, hidden row 1 (0,0)") |
| << 4 << 4 << 1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveDown << Qt::NoModifier |
| << 2 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveDown, hidden row 3 (2,0)") |
| << 4 << 4 << 3 << -1 |
| << 2 << 0 |
| << QtTestTableView::MoveDown << 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 |
| << QtTestTableView::MoveDown << Qt::NoModifier |
| << 1 << 1 << IntPair(0,0) << IntPair(0,0); |
| |
| // MoveUp |
| QTest::newRow("MoveUp (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveUp << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveUp (3, 0)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 0 |
| << QtTestTableView::MoveUp << Qt::NoModifier |
| << 2 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveUp (0,1)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 1 |
| << QtTestTableView::MoveUp << Qt::NoModifier |
| << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveUp, hidden row 1 (2,0)") |
| << 4 << 4 << 1 << -1 |
| << 2 << 0 |
| << QtTestTableView::MoveUp << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveUp, hidden row (1,0)") |
| << 4 << 4 << 0 << -1 |
| << 1 << 0 |
| << QtTestTableView::MoveUp << Qt::NoModifier |
| << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| // MoveHome |
| QTest::newRow("MoveHome (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveHome << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveHome (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveHome << Qt::NoModifier |
| << 3 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveHome, hidden column 0 (3,3)") |
| << 4 << 4 << -1 << 0 |
| << 3 << 3 |
| << QtTestTableView::MoveHome << 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 |
| << QtTestTableView::MoveHome << Qt::ControlModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveHome + Ctrl (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveHome << 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 |
| << QtTestTableView::MoveHome << Qt::ControlModifier |
| << 1 << 1 << IntPair(0,0) << IntPair(0,0); |
| |
| // MoveEnd |
| QTest::newRow("MoveEnd (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MoveEnd << Qt::NoModifier |
| << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveEnd (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveEnd << Qt::NoModifier |
| << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveEnd, hidden column (0,0)") |
| << 4 << 4 << -1 << 3 |
| << 0 << 0 |
| << QtTestTableView::MoveEnd << 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 |
| << QtTestTableView::MoveEnd << Qt::ControlModifier |
| << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MoveEnd + Ctrl (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MoveEnd << 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 |
| << QtTestTableView::MoveEnd << 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 |
| << QtTestTableView::MoveEnd << Qt::ControlModifier |
| << 2 << 2 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePageUp (0,0)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 0 |
| << QtTestTableView::MovePageUp << Qt::NoModifier |
| << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePageUp (3,3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MovePageUp << Qt::NoModifier |
| << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePageDown (3, 3)") |
| << 4 << 4 << -1 << -1 |
| << 3 << 3 |
| << QtTestTableView::MovePageDown << Qt::NoModifier |
| << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
| |
| QTest::newRow("MovePageDown (0, 3)") |
| << 4 << 4 << -1 << -1 |
| << 0 << 3 |
| << QtTestTableView::MovePageDown << Qt::NoModifier |
| << 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(QtTestTableView::CursorAction, cursorMoveAction); |
| QFETCH(Qt::KeyboardModifier, modifier); |
| QFETCH(int, expectedRow); |
| QFETCH(int, expectedColumn); |
| QFETCH(IntPair, moveRow); |
| QFETCH(IntPair, moveColumn); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QtTestTableView view; |
| |
| view.setModel(&model); |
| // we have to make sure that PgUp/PgDown can scroll to the bottom/top |
| view.resize(view.horizontalHeader()->length() + 50, |
| view.verticalHeader()->length() + 50); |
| 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(cursorMoveAction, modifier); |
| // expected fails, task 119433 |
| if(newIndex.row() == -1) |
| return; |
| QCOMPARE(newIndex.row(), expectedRow); |
| QCOMPARE(newIndex.column(), expectedColumn); |
| } |
| |
| void tst_QTableView::moveCursorStrikesBack_data() |
| { |
| QTest::addColumn<int>("hideRow"); |
| QTest::addColumn<int>("hideColumn"); |
| QTest::addColumn<IntList>("disableRows"); |
| QTest::addColumn<IntList>("disableColumns"); |
| QTest::addColumn<QRect>("span"); |
| |
| QTest::addColumn<int>("startRow"); |
| QTest::addColumn<int>("startColumn"); |
| QTest::addColumn<CursorActionList>("cursorMoveActions"); |
| QTest::addColumn<int>("expectedRow"); |
| QTest::addColumn<int>("expectedColumn"); |
| |
| QTest::newRow("Last column disabled. Task QTBUG-3878") << -1 << -1 |
| << IntList() |
| << (IntList() << 6) |
| << QRect() |
| << 0 << 5 |
| << CursorActionList{QtTestTableView::MoveNext} |
| << 1 << 0; |
| |
| QTest::newRow("Last column disabled 2. Task QTBUG-3878") << -1 << -1 |
| << IntList() |
| << (IntList() << 6) |
| << QRect() |
| << 1 << 0 |
| << CursorActionList{QtTestTableView::MovePrevious} |
| << 0 << 5; |
| |
| QTest::newRow("Span, anchor column hidden") << -1 << 1 |
| << IntList() |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 2 << 0 |
| << CursorActionList{QtTestTableView::MoveNext} |
| << 2 << 1; |
| |
| QTest::newRow("Span, anchor column disabled") << -1 << -1 |
| << IntList() |
| << (IntList() << 1) |
| << QRect(1, 2, 2, 3) |
| << 2 << 0 |
| << CursorActionList{QtTestTableView::MoveNext} |
| << 2 << 1; |
| |
| QTest::newRow("Span, anchor row hidden") << 2 << -1 |
| << IntList() |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 1 << 2 |
| << CursorActionList{QtTestTableView::MoveDown} |
| << 2 << 1; |
| |
| QTest::newRow("Span, anchor row disabled") << -1 << -1 |
| << (IntList() << 2) |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 1 << 2 |
| << CursorActionList{QtTestTableView::MoveDown} |
| << 2 << 1; |
| |
| QTest::newRow("Move through span right") << -1 << -1 |
| << IntList() |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 3 << 0 |
| << CursorActionList{QtTestTableView::MoveRight, |
| QtTestTableView::MoveRight} |
| << 3 << 3; |
| |
| QTest::newRow("Move through span left") << -1 << -1 |
| << IntList() |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 3 << 3 |
| << CursorActionList{QtTestTableView::MoveLeft, |
| QtTestTableView::MoveLeft} |
| << 3 << 0; |
| |
| QTest::newRow("Move through span down") << -1 << -1 |
| << IntList() |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 1 << 2 |
| << CursorActionList{QtTestTableView::MoveDown, |
| QtTestTableView::MoveDown} |
| << 5 << 2; |
| |
| QTest::newRow("Move through span up") << -1 << -1 |
| << IntList() |
| << IntList() |
| << QRect(1, 2, 2, 3) |
| << 5 << 2 |
| << CursorActionList{QtTestTableView::MoveUp, |
| QtTestTableView::MoveUp} |
| << 1 << 2; |
| |
| IntList fullList; |
| for (int i = 0; i < 7; ++i) |
| fullList << i; |
| |
| QTest::newRow("All disabled, wrap forward. => invalid index") << -1 << -1 |
| << fullList |
| << fullList |
| << QRect() |
| << 1 << 0 |
| << CursorActionList{QtTestTableView::MoveNext} |
| << -1 << -1; |
| |
| QTest::newRow("All disabled, wrap backwards. => invalid index") << -1 << -1 |
| << fullList |
| << fullList |
| << QRect() |
| << 1 << 0 |
| << CursorActionList{QtTestTableView::MovePrevious} |
| << -1 << -1; |
| |
| QTest::newRow("Last column disabled, MoveEnd. QTBUG-72400") << -1 << -1 |
| << IntList() |
| << (IntList() << 6) |
| << QRect() |
| << 0 << 0 |
| << CursorActionList{QtTestTableView::MoveEnd} |
| << 0 << 5; |
| |
| QTest::newRow("First column disabled, MoveHome. QTBUG-72400") << -1 << -1 |
| << IntList() |
| << (IntList() << 0) |
| << QRect() |
| << 0 << 6 |
| << CursorActionList{QtTestTableView::MoveHome} |
| << 0 << 1; |
| |
| QTest::newRow("First row disabled, MovePageUp. QTBUG-72400") << -1 << -1 |
| << (IntList() << 0) |
| << IntList() |
| << QRect() |
| << 2 << 0 |
| << CursorActionList{QtTestTableView::MovePageUp} |
| << 1 << 0; |
| |
| QTest::newRow("Last row disabled, MovePageDown. QTBUG-72400") << -1 << -1 |
| << (IntList() << 6) |
| << IntList() |
| << QRect() |
| << 4 << 0 |
| << CursorActionList{QtTestTableView::MovePageDown} |
| << 5 << 0; |
| } |
| |
| void tst_QTableView::moveCursorStrikesBack() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QFETCH(int, hideRow); |
| QFETCH(int, hideColumn); |
| QFETCH(const IntList, disableRows); |
| QFETCH(const IntList, disableColumns); |
| QFETCH(QRect, span); |
| |
| QFETCH(int, startRow); |
| QFETCH(int, startColumn); |
| QFETCH(const CursorActionList, 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(); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| // resize to make sure there are scrollbars |
| view.resize(view.columnWidth(0) * 7, view.rowHeight(0) * 7); |
| |
| QModelIndex index = model.index(startRow, startColumn); |
| view.setCurrentIndex(index); |
| |
| for (int row : disableRows) |
| model.disableRow(row); |
| for (int column : disableColumns) |
| model.disableColumn(column); |
| |
| int newRow = -1; |
| int newColumn = -1; |
| for (auto cursorMoveAction : cursorMoveActions) { |
| QModelIndex newIndex = view.moveCursor(cursorMoveAction, {}); |
| view.setCurrentIndex(newIndex); |
| newRow = newIndex.row(); |
| newColumn = newIndex.column(); |
| } |
| |
| QCOMPARE(newRow, expectedRow); |
| QCOMPARE(newColumn, expectedColumn); |
| } |
| |
| void tst_QTableView::moveCursorBiggerJump() |
| { |
| QtTestTableModel model(50, 7); |
| QTableView view; |
| view.setModel(&model); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| |
| int height = view.horizontalHeader()->height(); |
| for (int i=0;i<8;i++) |
| height += view.verticalHeader()->sectionSize(i); |
| view.resize(view.width(), height); |
| view.setCurrentIndex(model.index(0,0)); |
| |
| QTest::keyClick(&view, Qt::Key_PageDown); |
| QCOMPARE(view.indexAt(QPoint(0,0)), model.index(1,0)); |
| QTest::keyClick(&view, Qt::Key_PageDown); |
| QCOMPARE(view.indexAt(QPoint(0,0)), model.index(8,0)); |
| QTest::keyClick(&view, Qt::Key_PageDown); |
| QCOMPARE(view.indexAt(QPoint(0,0)), model.index(15,0)); |
| QTest::keyClick(&view, Qt::Key_PageUp); |
| QCOMPARE(view.indexAt(QPoint(0,0)), model.index(14,0)); |
| QTest::keyClick(&view, Qt::Key_PageUp); |
| QCOMPARE(view.indexAt(QPoint(0,0)), model.index(7,0)); |
| QTest::keyClick(&view, Qt::Key_PageUp); |
| QCOMPARE(view.indexAt(QPoint(0,0)), model.index(0,0)); |
| |
| QTest::keyClick(&view, Qt::Key_PageDown); |
| view.verticalHeader()->hideSection(0); |
| QTest::keyClick(&view, Qt::Key_PageUp); |
| QTRY_COMPARE(view.currentIndex().row(), view.rowAt(0)); |
| } |
| |
| void tst_QTableView::hideRows_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("showRow"); // hide, then show |
| QTest::addColumn<int>("hideRow"); // hide only |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| |
| QTest::newRow("show row 0, hide row 3, no span") |
| << 10 << 10 |
| << 0 |
| << 3 |
| << -1 << -1 |
| << 1 << 1; |
| |
| QTest::newRow("show row 0, hide row 3, span") |
| << 10 << 10 |
| << 0 |
| << 3 |
| << 0 << 0 |
| << 3 << 2; |
| } |
| |
| void tst_QTableView::hideRows() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, showRow); |
| QFETCH(int, hideRow); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowSpan); |
| QFETCH(int, columnSpan); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QTableView view; |
| |
| view.setModel(&model); |
| view.setSpan(row, column, rowSpan, columnSpan); |
| |
| view.hideRow(showRow); |
| QVERIFY(view.isRowHidden(showRow)); |
| |
| view.hideRow(hideRow); |
| QVERIFY(view.isRowHidden(hideRow)); |
| |
| view.showRow(showRow); |
| QVERIFY(!view.isRowHidden(showRow)); |
| QVERIFY(view.isRowHidden(hideRow)); |
| } |
| |
| void tst_QTableView::hideColumns_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("showColumn"); // hide, then show |
| QTest::addColumn<int>("hideColumn"); // hide only |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| |
| QTest::newRow("show col 0, hide col 3, no span") |
| << 10 << 10 |
| << 0 |
| << 3 |
| << -1 << -1 |
| << 1 << 1; |
| |
| QTest::newRow("show col 0, hide col 3, span") |
| << 10 << 10 |
| << 0 |
| << 3 |
| << 0 << 0 |
| << 3 << 2; |
| } |
| |
| void tst_QTableView::hideColumns() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, showColumn); |
| QFETCH(int, hideColumn); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowSpan); |
| QFETCH(int, columnSpan); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| |
| QTableView view; |
| view.setModel(&model); |
| view.setSpan(row, column, rowSpan, columnSpan); |
| |
| view.hideColumn(showColumn); |
| QVERIFY(view.isColumnHidden(showColumn)); |
| |
| view.hideColumn(hideColumn); |
| QVERIFY(view.isColumnHidden(hideColumn)); |
| |
| view.showColumn(showColumn); |
| QVERIFY(!view.isColumnHidden(showColumn)); |
| QVERIFY(view.isColumnHidden(hideColumn)); |
| } |
| |
| void tst_QTableView::selection_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| QTest::addColumn<int>("hideRow"); |
| QTest::addColumn<int>("hideColumn"); |
| QTest::addColumn<int>("moveRowFrom"); |
| QTest::addColumn<int>("moveRowTo"); |
| QTest::addColumn<int>("moveColumnFrom"); |
| QTest::addColumn<int>("moveColumnTo"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| QTest::addColumn<int>("x"); |
| QTest::addColumn<int>("y"); |
| QTest::addColumn<int>("width"); |
| QTest::addColumn<int>("height"); |
| QTest::addColumn<QItemSelectionModel::SelectionFlag>("command"); |
| QTest::addColumn<int>("selectedCount"); // ### make this more detailed |
| |
| QTest::newRow("no span, no hidden, no moved, 3x3 select") |
| << 10 << 10 // dim |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << -1 << -1 // hide |
| << -1 << -1 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 20 << 20 << 80 << 80 // rect |
| << 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 |
| << 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 |
| << 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 |
| << 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 |
| << 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 |
| << 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 |
| << 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(QItemSelectionModel::SelectionFlag, 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), command); |
| |
| QCOMPARE(view.selectedIndexes().count(), selectedCount); |
| } |
| |
| void tst_QTableView::selectRow_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<QAbstractItemView::SelectionMode>("mode"); |
| QTest::addColumn<QAbstractItemView::SelectionBehavior>("behavior"); |
| QTest::addColumn<int>("selectedItems"); |
| |
| QTest::newRow("SingleSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::SingleSelection |
| << QAbstractItemView::SelectItems |
| << 0; |
| |
| QTest::newRow("SingleSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::SingleSelection |
| << QAbstractItemView::SelectRows |
| << 10; |
| |
| QTest::newRow("SingleSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::SingleSelection |
| << QAbstractItemView::SelectColumns |
| << 0; |
| |
| QTest::newRow("MultiSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::MultiSelection |
| << QAbstractItemView::SelectItems |
| << 10; |
| |
| QTest::newRow("MultiSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::MultiSelection |
| << QAbstractItemView::SelectRows |
| << 10; |
| |
| QTest::newRow("MultiSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::MultiSelection |
| << QAbstractItemView::SelectColumns |
| << 0; |
| |
| QTest::newRow("ExtendedSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ExtendedSelection |
| << QAbstractItemView::SelectItems |
| << 10; |
| |
| QTest::newRow("ExtendedSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ExtendedSelection |
| << QAbstractItemView::SelectRows |
| << 10; |
| |
| QTest::newRow("ExtendedSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ExtendedSelection |
| << QAbstractItemView::SelectColumns |
| << 0; |
| |
| QTest::newRow("ContiguousSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ContiguousSelection |
| << QAbstractItemView::SelectItems |
| << 10; |
| |
| QTest::newRow("ContiguousSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ContiguousSelection |
| << QAbstractItemView::SelectRows |
| << 10; |
| |
| QTest::newRow("ContiguousSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ContiguousSelection |
| << QAbstractItemView::SelectColumns |
| << 0; |
| } |
| |
| void tst_QTableView::selectRow() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, row); |
| QFETCH(QAbstractItemView::SelectionMode, mode); |
| QFETCH(QAbstractItemView::SelectionBehavior, behavior); |
| QFETCH(int, selectedItems); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QTableView view; |
| |
| view.setModel(&model); |
| view.setSelectionMode(mode); |
| view.setSelectionBehavior(behavior); |
| |
| QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0); |
| |
| view.selectRow(row); |
| |
| //test we have 10 items selected |
| QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems); |
| //test that all 10 items are in the same row |
| for (int i = 0; selectedItems > 0 && i < rowCount; ++i) |
| QCOMPARE(view.selectionModel()->selectedIndexes().at(i).row(), row); |
| } |
| |
| void tst_QTableView::selectColumn_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<QAbstractItemView::SelectionMode>("mode"); |
| QTest::addColumn<QAbstractItemView::SelectionBehavior>("behavior"); |
| QTest::addColumn<int>("selectedItems"); |
| |
| QTest::newRow("SingleSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::SingleSelection |
| << QAbstractItemView::SelectItems |
| << 0; |
| |
| QTest::newRow("SingleSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::SingleSelection |
| << QAbstractItemView::SelectRows |
| << 0; |
| |
| QTest::newRow("SingleSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::SingleSelection |
| << QAbstractItemView::SelectColumns |
| << 10; |
| |
| QTest::newRow("MultiSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::MultiSelection |
| << QAbstractItemView::SelectItems |
| << 10; |
| |
| QTest::newRow("MultiSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::MultiSelection |
| << QAbstractItemView::SelectRows |
| << 0; |
| |
| QTest::newRow("MultiSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::MultiSelection |
| << QAbstractItemView::SelectColumns |
| << 10; |
| |
| QTest::newRow("ExtendedSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ExtendedSelection |
| << QAbstractItemView::SelectItems |
| << 10; |
| |
| QTest::newRow("ExtendedSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ExtendedSelection |
| << QAbstractItemView::SelectRows |
| << 0; |
| |
| QTest::newRow("ExtendedSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ExtendedSelection |
| << QAbstractItemView::SelectColumns |
| << 10; |
| |
| QTest::newRow("ContiguousSelection and SelectItems") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ContiguousSelection |
| << QAbstractItemView::SelectItems |
| << 10; |
| |
| QTest::newRow("ContiguousSelection and SelectRows") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ContiguousSelection |
| << QAbstractItemView::SelectRows |
| << 0; |
| |
| QTest::newRow("ContiguousSelection and SelectColumns") |
| << 10 << 10 |
| << 0 |
| << QAbstractItemView::ContiguousSelection |
| << QAbstractItemView::SelectColumns |
| << 10; |
| } |
| |
| void tst_QTableView::selectColumn() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, column); |
| QFETCH(QAbstractItemView::SelectionMode, mode); |
| QFETCH(QAbstractItemView::SelectionBehavior, behavior); |
| QFETCH(int, selectedItems); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| |
| QTableView view; |
| view.setModel(&model); |
| view.setSelectionMode(mode); |
| view.setSelectionBehavior(behavior); |
| |
| QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0); |
| |
| view.selectColumn(column); |
| |
| QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems); |
| for (int i = 0; selectedItems > 0 && i < columnCount; ++i) |
| QCOMPARE(view.selectionModel()->selectedIndexes().at(i).column(), column); |
| } |
| |
| void tst_QTableView::selectall_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| QTest::addColumn<int>("hideRow"); |
| QTest::addColumn<int>("hideColumn"); |
| QTest::addColumn<int>("moveRowFrom"); |
| QTest::addColumn<int>("moveRowTo"); |
| QTest::addColumn<int>("moveColumnFrom"); |
| QTest::addColumn<int>("moveColumnTo"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| QTest::addColumn<int>("selectedCount"); // ### make this more detailed |
| |
| QTest::newRow("no span, no hidden, no moved") |
| << 10 << 10 // dim |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << -1 << -1 // hide |
| << -1 << -1 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 100; // selected count |
| |
| QTest::newRow("row span, no hidden, no moved") |
| << 10 << 10 // dim |
| << 1 << 1 // pos |
| << 2 << 1 // span |
| << -1 << -1 // hide |
| << -1 << -1 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 99; // selected count |
| |
| QTest::newRow("col span, no hidden, no moved") |
| << 10 << 10 // dim |
| << 1 << 1 // pos |
| << 1 << 2 // span |
| << -1 << -1 // hide |
| << -1 << -1 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 99; // selected count |
| |
| QTest::newRow("no span, row hidden, no moved") |
| << 10 << 10 // dim |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 1 << -1 // hide |
| << -1 << -1 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 90; // selected count |
| |
| QTest::newRow("no span, col hidden, no moved") |
| << 10 << 10 // dim |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << -1 << 1 // hide |
| << -1 << -1 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 90; // selected count |
| |
| QTest::newRow("no span, no hidden, row moved") |
| << 10 << 10 // dim |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << -1 << -1 // hide |
| << 1 << 3 // move row |
| << -1 << -1 // move col |
| << 40 << 40 // cell size |
| << 100; // selected count |
| |
| QTest::newRow("no span, no hidden, col moved") |
| << 10 << 10 // dim |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << -1 << -1 // hide |
| << -1 << -1 // move row |
| << 1 << 3 // move col |
| << 40 << 40 // cell size |
| << 100; // selected count |
| } |
| |
| void QTest__keySequence(QWidget* widget, const QKeySequence &ks) |
| { |
| for (int i = 0; i < ks.count(); ++i) |
| { |
| Qt::Key key = Qt::Key(ks[i] & ~Qt::KeyboardModifierMask); |
| Qt::KeyboardModifiers modifiers = Qt::KeyboardModifiers(ks[i] & Qt::KeyboardModifierMask); |
| QTest::keyClick(widget, key, modifiers); |
| } |
| } |
| |
| void tst_QTableView::selectall() |
| { |
| 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, 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); |
| |
| // try slot first |
| view.clearSelection(); |
| QCOMPARE(view.selectedIndexes().count(), 0); |
| view.selectAll(); |
| QCOMPARE(view.selectedIndexes().count(), selectedCount); |
| |
| // try by key sequence |
| view.clearSelection(); |
| QCOMPARE(view.selectedIndexes().count(), 0); |
| QTest__keySequence(&view, QKeySequence(QKeySequence::SelectAll)); |
| QCOMPARE(view.selectedIndexes().count(), selectedCount); |
| |
| // check again with no selection mode |
| view.clearSelection(); |
| view.setSelectionMode(QAbstractItemView::NoSelection); |
| QCOMPARE(view.selectedIndexes().count(), 0); |
| QTest__keySequence(&view, QKeySequence(QKeySequence::SelectAll)); |
| QCOMPARE(view.selectedIndexes().count(), 0); |
| } |
| |
| void tst_QTableView::visualRect_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("hideRow"); |
| QTest::addColumn<int>("hideColumn"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| QTest::addColumn<QRect>("expectedRect"); |
| |
| QTest::newRow("(0,0)") |
| << 10 << 10 |
| << -1 << -1 |
| << 0 << 0 |
| << 20 << 30 |
| << QRect(0, 0, 29, 19); |
| |
| QTest::newRow("(0,0) hidden row") |
| << 10 << 10 |
| << 0 << -1 |
| << 0 << 0 |
| << 20 << 30 |
| << QRect(); |
| |
| QTest::newRow("(0,0) hidden column") |
| << 10 << 10 |
| << -1 << 0 |
| << 0 << 0 |
| << 20 << 30 |
| << QRect(); |
| |
| QTest::newRow("(0,0) hidden row and column") |
| << 10 << 10 |
| << 0 << 0 |
| << 0 << 0 |
| << 20 << 30 |
| << QRect(); |
| |
| QTest::newRow("(0,0) out of bounds") |
| << 10 << 10 |
| << -1 << -1 |
| << 20 << 20 |
| << 20 << 30 |
| << QRect(); |
| |
| QTest::newRow("(5,5), hidden row") |
| << 10 << 10 |
| << 5 << -1 |
| << 5 << 5 |
| << 20 << 30 |
| << QRect(); |
| |
| QTest::newRow("(9,9)") |
| << 10 << 10 |
| << -1 << -1 |
| << 9 << 9 |
| << 20 << 30 |
| << QRect(30*9, 20*9, 29, 19); |
| } |
| |
| void tst_QTableView::visualRect() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, hideRow); |
| QFETCH(int, hideColumn); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowHeight); |
| QFETCH(int, columnWidth); |
| QFETCH(QRect, expectedRect); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| |
| QTableView view; |
| view.setModel(&model); |
| view.horizontalHeader()->setMinimumSectionSize(0); |
| view.verticalHeader()->setMinimumSectionSize(0); |
| // Make sure that it has 1 pixel between each cell. |
| view.setGridStyle(Qt::SolidLine); |
| for (int i = 0; i < view.verticalHeader()->count(); ++i) |
| view.verticalHeader()->resizeSection(i, rowHeight); |
| for (int i = 0; i < view.horizontalHeader()->count(); ++i) |
| view.horizontalHeader()->resizeSection(i, columnWidth); |
| |
| view.hideRow(hideRow); |
| view.hideColumn(hideColumn); |
| |
| QRect rect = view.visualRect(model.index(row, column)); |
| QCOMPARE(rect, expectedRect); |
| } |
| |
| void tst_QTableView::fetchMore() |
| { |
| QtTestTableModel model(64, 64); |
| |
| model.can_fetch_more = true; |
| |
| QTableView view; |
| view.setModel(&model); |
| view.show(); |
| |
| QCOMPARE(model.fetch_more_count, 0); |
| view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum()); |
| QVERIFY(model.fetch_more_count > 0); |
| |
| model.fetch_more_count = 0; //reset |
| view.scrollToTop(); |
| QCOMPARE(model.fetch_more_count, 0); |
| |
| view.scrollToBottom(); |
| QVERIFY(model.fetch_more_count > 0); |
| |
| model.fetch_more_count = 0; //reset |
| view.scrollToTop(); |
| view.setCurrentIndex(model.index(0, 0)); |
| QCOMPARE(model.fetch_more_count, 0); |
| |
| for (int i = 0; i < 64; ++i) |
| QTest::keyClick(&view, Qt::Key_Down); |
| QCOMPARE(view.currentIndex(), model.index(63, 0)); |
| QVERIFY(model.fetch_more_count > 0); |
| } |
| |
| void tst_QTableView::setHeaders() |
| { |
| QTableView view; |
| |
| // Make sure we don't delete ourselves |
| view.setVerticalHeader(view.verticalHeader()); |
| view.verticalHeader()->count(); |
| view.setHorizontalHeader(view.horizontalHeader()); |
| view.horizontalHeader()->count(); |
| |
| // Try passing around a header without it being deleted |
| QTableView view2; |
| view2.setVerticalHeader(view.verticalHeader()); |
| view2.setHorizontalHeader(view.horizontalHeader()); |
| view.setHorizontalHeader(new QHeaderView(Qt::Horizontal)); |
| view.setVerticalHeader(new QHeaderView(Qt::Vertical)); |
| view2.verticalHeader()->count(); |
| view2.horizontalHeader()->count(); |
| |
| } |
| |
| void tst_QTableView::resizeRowsToContents_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<bool>("showGrid"); |
| QTest::addColumn<int>("cellWidth"); |
| QTest::addColumn<int>("cellHeight"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| |
| QTest::newRow("10x10 grid shown 40x40") |
| << 10 << 10 << false << 40 << 40 << 40 << 40; |
| |
| QTest::newRow("10x10 grid not shown 40x40") |
| << 10 << 10 << true << 40 << 40 << 41 << 41; |
| } |
| |
| void tst_QTableView::resizeRowsToContents() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(bool, showGrid); |
| QFETCH(int, cellWidth); |
| QFETCH(int, cellHeight); |
| QFETCH(int, rowHeight); |
| QFETCH(int, columnWidth); |
| Q_UNUSED(columnWidth) |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QtTestTableView view; |
| QtTestItemDelegate delegate; |
| |
| view.setModel(&model); |
| view.setItemDelegate(&delegate); |
| view.setShowGrid(showGrid); // the grid will add to the row height |
| |
| delegate.hint = QSize(cellWidth, cellHeight); |
| |
| QSignalSpy resizedSpy(view.verticalHeader(), &QHeaderView::sectionResized); |
| view.resizeRowsToContents(); |
| |
| QCOMPARE(resizedSpy.count(), model.rowCount()); |
| for (int r = 0; r < model.rowCount(); ++r) |
| QCOMPARE(view.rowHeight(r), rowHeight); |
| } |
| |
| void tst_QTableView::resizeColumnsToContents_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<bool>("showGrid"); |
| QTest::addColumn<int>("cellWidth"); |
| QTest::addColumn<int>("cellHeight"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| |
| QTest::newRow("10x10 grid not shown 60x60") |
| << 10 << 10 << false << 60 << 60 << 60 << 60; |
| |
| QTest::newRow("10x10 grid shown 60x60") |
| << 10 << 10 << true << 60 << 60 << 61 << 61; |
| } |
| |
| 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(), &QHeaderView::sectionResized); |
| view.resizeColumnsToContents(); |
| |
| QCOMPARE(resizedSpy.count(), model.columnCount()); |
| for (int c = 0; c < model.columnCount(); ++c) |
| QCOMPARE(view.columnWidth(c), columnWidth); |
| } |
| |
| void tst_QTableView::rowViewportPosition_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<QAbstractItemView::ScrollMode>("verticalScrollMode"); |
| QTest::addColumn<int>("verticalScrollValue"); |
| QTest::addColumn<int>("rowViewportPosition"); |
| |
| QTest::newRow("row 0, scroll per item 0") |
| << 10 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0; |
| |
| QTest::newRow("row 1, scroll per item, 0") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40; |
| |
| QTest::newRow("row 1, scroll per item, 1") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0; |
| |
| QTest::newRow("row 5, scroll per item, 0") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40; |
| |
| QTest::newRow("row 5, scroll per item, 5") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0; |
| |
| QTest::newRow("row 9, scroll per item, 0") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40; |
| |
| QTest::newRow("row 9, scroll per item, 5") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40; |
| |
| QTest::newRow("row 0, scroll per pixel 0") |
| << 10 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0; |
| |
| QTest::newRow("row 1, scroll per pixel, 0") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40; |
| |
| QTest::newRow("row 1, scroll per pixel, 1") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0; |
| |
| QTest::newRow("row 5, scroll per pixel, 0") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40; |
| |
| QTest::newRow("row 5, scroll per pixel, 5") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0; |
| |
| QTest::newRow("row 9, scroll per pixel, 0") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40; |
| |
| QTest::newRow("row 9, scroll per pixel, 5") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40; |
| } |
| |
| void tst_QTableView::rowViewportPosition() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, rowHeight); |
| QFETCH(int, row); |
| QFETCH(QAbstractItemView::ScrollMode, verticalScrollMode); |
| QFETCH(int, verticalScrollValue); |
| QFETCH(int, rowViewportPosition); |
| |
| QtTestTableModel model(rowCount, 1); |
| QtTestTableView view; |
| setFrameless(&view); |
| view.resize(100, 2 * rowHeight); |
| view.show(); |
| |
| view.setModel(&model); |
| for (int r = 0; r < rowCount; ++r) |
| view.setRowHeight(r, rowHeight); |
| |
| view.setVerticalScrollMode(verticalScrollMode); |
| view.verticalScrollBar()->setValue(verticalScrollValue); |
| |
| #ifdef Q_OS_WINRT |
| QEXPECT_FAIL("row 1, scroll per item, 1", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("row 5, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("row 9, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("row 1, scroll per pixel, 1", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("row 5, scroll per pixel, 5", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("row 9, scroll per pixel, 5", "Fails on WinRT - QTBUG-68297", Abort); |
| #endif |
| QCOMPARE(view.rowViewportPosition(row), rowViewportPosition); |
| } |
| |
| void tst_QTableView::rowAt_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<IntList>("hiddenRows"); |
| QTest::addColumn<int>("coordinate"); |
| QTest::addColumn<int>("row"); |
| |
| QTest::newRow("row at 100") << 5 << 40 << IntList() << 100 << 2; |
| QTest::newRow("row at 180") << 5 << 40 << IntList() << 180 << 4; |
| QTest::newRow("row at 20") << 5 << 40 << IntList() << 20 << 0; |
| |
| // ### expand the dataset to include hidden rows |
| } |
| |
| void tst_QTableView::rowAt() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, rowHeight); |
| QFETCH(IntList, hiddenRows); |
| QFETCH(int, coordinate); |
| QFETCH(int, row); |
| |
| QtTestTableModel model(rowCount, 1); |
| QtTestTableView view; |
| view.resize(100, 2 * rowHeight); |
| |
| view.setModel(&model); |
| |
| for (int r = 0; r < rowCount; ++r) |
| view.setRowHeight(r, rowHeight); |
| |
| for (int i = 0; i < hiddenRows.count(); ++i) |
| view.hideRow(hiddenRows.at(i)); |
| |
| QCOMPARE(view.rowAt(coordinate), row); |
| } |
| |
| void tst_QTableView::rowHeight_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<IntList>("rowHeights"); |
| QTest::addColumn<BoolList>("hiddenRows"); |
| |
| QTest::newRow("increasing") |
| << 5 |
| << (IntList() << 20 << 30 << 40 << 50 << 60) |
| << (BoolList() << false << false << false << false << false); |
| |
| QTest::newRow("decreasing") |
| << 5 |
| << (IntList() << 60 << 50 << 40 << 30 << 20) |
| << (BoolList() << false << false << false << false << false); |
| |
| QTest::newRow("random") |
| << 5 |
| << (IntList() << 87 << 34 << 68 << 91 << 27) |
| << (BoolList() << false << false << false << false << false); |
| |
| // ### expand the dataset to include hidden rows |
| } |
| |
| void tst_QTableView::rowHeight() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(IntList, rowHeights); |
| QFETCH(BoolList, hiddenRows); |
| |
| QtTestTableModel model(rowCount, 1); |
| QtTestTableView view; |
| |
| view.setModel(&model); |
| |
| for (int r = 0; r < rowCount; ++r) { |
| view.setRowHeight(r, rowHeights.at(r)); |
| view.setRowHidden(r, hiddenRows.at(r)); |
| } |
| |
| for (int r = 0; r < rowCount; ++r) { |
| if (hiddenRows.at(r)) |
| QCOMPARE(view.rowHeight(r), 0); |
| else |
| QCOMPARE(view.rowHeight(r), rowHeights.at(r)); |
| } |
| } |
| |
| void tst_QTableView::columnViewportPosition_data() |
| { |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("columnWidth"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<QAbstractItemView::ScrollMode>("horizontalScrollMode"); |
| QTest::addColumn<int>("horizontalScrollValue"); |
| QTest::addColumn<int>("columnViewportPosition"); |
| |
| QTest::newRow("column 0, scroll per item 0") |
| << 10 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0; |
| |
| QTest::newRow("column 1, scroll per item, 0") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40; |
| |
| QTest::newRow("column 1, scroll per item, 1") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0; |
| |
| QTest::newRow("column 5, scroll per item, 0") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40; |
| |
| QTest::newRow("column 5, scroll per item, 5") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0; |
| |
| QTest::newRow("column 9, scroll per item, 0") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40; |
| |
| QTest::newRow("column 9, scroll per item, 5") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40; |
| |
| QTest::newRow("column 0, scroll per pixel 0") |
| << 10 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0; |
| |
| QTest::newRow("column 1, scroll per pixel 0") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40; |
| |
| QTest::newRow("column 1, scroll per pixel 1") |
| << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0; |
| |
| QTest::newRow("column 5, scroll per pixel 0") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40; |
| |
| QTest::newRow("column 5, scroll per pixel 5") |
| << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0; |
| |
| QTest::newRow("column 9, scroll per pixel 0") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40; |
| |
| QTest::newRow("column 9, scroll per pixel 5") |
| << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40; |
| } |
| |
| void tst_QTableView::columnViewportPosition() |
| { |
| QFETCH(int, columnCount); |
| QFETCH(int, columnWidth); |
| QFETCH(int, column); |
| QFETCH(QAbstractItemView::ScrollMode, horizontalScrollMode); |
| QFETCH(int, horizontalScrollValue); |
| QFETCH(int, columnViewportPosition); |
| |
| QtTestTableModel model(1, columnCount); |
| QtTestTableView view; |
| setFrameless(&view); |
| view.resize(2 * columnWidth, 100); |
| view.show(); |
| |
| view.setModel(&model); |
| for (int c = 0; c < columnCount; ++c) |
| view.setColumnWidth(c, columnWidth); |
| |
| view.setHorizontalScrollMode(horizontalScrollMode); |
| view.horizontalScrollBar()->setValue(horizontalScrollValue); |
| |
| #ifdef Q_OS_WINRT |
| QEXPECT_FAIL("column 5, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("column 9, scroll per item, 5", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("column 1, scroll per pixel 1", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("column 5, scroll per pixel 5", "Fails on WinRT - QTBUG-68297", Abort); |
| QEXPECT_FAIL("column 9, scroll per pixel 5", "Fails on WinRT - QTBUG-68297", Abort); |
| #endif |
| QCOMPARE(view.columnViewportPosition(column), columnViewportPosition); |
| } |
| |
| void tst_QTableView::columnAt_data() |
| { |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("columnWidth"); |
| QTest::addColumn<IntList>("hiddenColumns"); |
| QTest::addColumn<int>("coordinate"); |
| QTest::addColumn<int>("column"); |
| |
| QTest::newRow("column at 100") << 5 << 40 << IntList() << 100 << 2; |
| QTest::newRow("column at 180") << 5 << 40 << IntList() << 180 << 4; |
| QTest::newRow("column at 20") << 5 << 40 << IntList() << 20 << 0; |
| |
| // ### expand the dataset to include hidden coumns |
| } |
| |
| void tst_QTableView::columnAt() |
| { |
| QFETCH(int, columnCount); |
| QFETCH(int, columnWidth); |
| QFETCH(IntList, hiddenColumns); |
| QFETCH(int, coordinate); |
| QFETCH(int, column); |
| |
| QtTestTableModel model(1, columnCount); |
| QtTestTableView view; |
| view.resize(2 * columnWidth, 100); |
| |
| view.setModel(&model); |
| |
| for (int c = 0; c < columnCount; ++c) |
| view.setColumnWidth(c, columnWidth); |
| |
| for (int i = 0; i < hiddenColumns.count(); ++i) |
| view.hideColumn(hiddenColumns.at(i)); |
| |
| QCOMPARE(view.columnAt(coordinate), column); |
| } |
| |
| void tst_QTableView::columnWidth_data() |
| { |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<IntList>("columnWidths"); |
| QTest::addColumn<BoolList>("hiddenColumns"); |
| |
| QTest::newRow("increasing") |
| << 5 |
| << (IntList() << 20 << 30 << 40 << 50 << 60) |
| << (BoolList() << false << false << false << false << false); |
| |
| QTest::newRow("decreasing") |
| << 5 |
| << (IntList() << 60 << 50 << 40 << 30 << 20) |
| << (BoolList() << false << false << false << false << false); |
| |
| QTest::newRow("random") |
| << 5 |
| << (IntList() << 87 << 34 << 68 << 91 << 27) |
| << (BoolList() << false << false << false << false << false); |
| |
| // ### expand the dataset to include hidden columns |
| } |
| |
| void tst_QTableView::columnWidth() |
| { |
| QFETCH(int, columnCount); |
| QFETCH(IntList, columnWidths); |
| QFETCH(BoolList, hiddenColumns); |
| |
| QtTestTableModel model(1, columnCount); |
| QtTestTableView view; |
| |
| view.setModel(&model); |
| |
| for (int c = 0; c < columnCount; ++c) { |
| view.setColumnWidth(c, columnWidths.at(c)); |
| view.setColumnHidden(c, hiddenColumns.at(c)); |
| } |
| |
| for (int c = 0; c < columnCount; ++c) { |
| if (hiddenColumns.at(c)) |
| QCOMPARE(view.columnWidth(c), 0); |
| else |
| QCOMPARE(view.columnWidth(c), columnWidths.at(c)); |
| } |
| } |
| |
| void tst_QTableView::hiddenRow_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<BoolList>("hiddenRows"); |
| |
| QTest::newRow("first hidden") |
| << 5 << (BoolList() << true << false << false << false << false); |
| |
| QTest::newRow("last hidden") |
| << 5 << (BoolList() << false << false << false << false << true); |
| |
| QTest::newRow("none hidden") |
| << 5 << (BoolList() << false << false << false << false << false); |
| |
| QTest::newRow("all hidden") |
| << 5 << (BoolList() << true << true << true << true << true); |
| } |
| |
| void tst_QTableView::hiddenRow() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(BoolList, hiddenRows); |
| |
| |
| QtTestTableModel model(rowCount, 1); |
| QtTestTableView view; |
| |
| view.setModel(&model); |
| |
| for (int r = 0; r < rowCount; ++r) |
| QVERIFY(!view.isRowHidden(r)); |
| |
| for (int r = 0; r < rowCount; ++r) |
| view.setRowHidden(r, hiddenRows.at(r)); |
| |
| for (int r = 0; r < rowCount; ++r) |
| QCOMPARE(view.isRowHidden(r), hiddenRows.at(r)); |
| |
| for (int r = 0; r < rowCount; ++r) |
| view.setRowHidden(r, false); |
| |
| for (int r = 0; r < rowCount; ++r) |
| QVERIFY(!view.isRowHidden(r)); |
| } |
| |
| void tst_QTableView::hiddenColumn_data() |
| { |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<BoolList>("hiddenColumns"); |
| |
| QTest::newRow("first hidden") |
| << 5 << (BoolList() << true << false << false << false << false); |
| |
| QTest::newRow("last hidden") |
| << 5 << (BoolList() << false << false << false << false << true); |
| |
| QTest::newRow("none hidden") |
| << 5 << (BoolList() << false << false << false << false << false); |
| |
| QTest::newRow("all hidden") |
| << 5 << (BoolList() << true << true << true << true << true); |
| } |
| |
| void tst_QTableView::hiddenColumn() |
| { |
| QFETCH(int, columnCount); |
| QFETCH(BoolList, hiddenColumns); |
| |
| QtTestTableModel model(1, columnCount); |
| QtTestTableView view; |
| |
| view.setModel(&model); |
| |
| for (int c = 0; c < columnCount; ++c) |
| QVERIFY(!view.isColumnHidden(c)); |
| |
| for (int c = 0; c < columnCount; ++c) |
| view.setColumnHidden(c, hiddenColumns.at(c)); |
| |
| for (int c = 0; c < columnCount; ++c) |
| QCOMPARE(view.isColumnHidden(c), hiddenColumns.at(c)); |
| |
| for (int c = 0; c < columnCount; ++c) |
| view.setColumnHidden(c, false); |
| |
| for (int c = 0; c < columnCount; ++c) |
| QVERIFY(!view.isColumnHidden(c)); |
| } |
| |
| void tst_QTableView::sortingEnabled_data() |
| { |
| // QTest::addColumn<int>("columnCount"); |
| } |
| |
| void tst_QTableView::sortingEnabled() |
| { |
| // QFETCH(int, columnCount); |
| } |
| |
| void tst_QTableView::scrollTo_data() |
| { |
| QTest::addColumn<QAbstractItemView::ScrollMode>("verticalScrollMode"); |
| QTest::addColumn<QAbstractItemView::ScrollMode>("horizontalScrollMode"); |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| QTest::addColumn<int>("hiddenRow"); |
| QTest::addColumn<int>("hiddenColumn"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| QTest::addColumn<int>("horizontalScroll"); |
| QTest::addColumn<int>("verticalScroll"); |
| QTest::addColumn<QAbstractItemView::ScrollHint>("scrollHint"); |
| QTest::addColumn<int>("expectedHorizontalScroll"); |
| QTest::addColumn<int>("expectedVerticalScroll"); |
| |
| QTest::newRow("no hidden, no span, no scroll, per item") |
| << QAbstractItemView::ScrollPerItem |
| << QAbstractItemView::ScrollPerItem |
| << 10 << 10 // table |
| << 80 << 80 // size |
| << -1 << -1 // hide |
| << 0 << 0 // cell |
| << 1 << 1 // span |
| << 0 << 0 // scroll |
| << QAbstractItemView::PositionAtTop |
| << 0 << 0; // expected |
| |
| QTest::newRow("no hidden, no span, no scroll, per pixel") |
| << QAbstractItemView::ScrollPerPixel |
| << QAbstractItemView::ScrollPerPixel |
| << 10 << 10 // table |
| << 80 << 80 // size |
| << -1 << -1 // hide |
| << 0 << 0 // cell |
| << 1 << 1 // span |
| << 0 << 0 // scroll |
| << QAbstractItemView::PositionAtTop |
| << 0 << 0; // expected |
| |
| QTest::newRow("hidden, no span, no scroll, per item") |
| << QAbstractItemView::ScrollPerItem |
| << QAbstractItemView::ScrollPerItem |
| << 10 << 10 // table |
| << 80 << 80 // size |
| << 3 << 3 // hide |
| << 5 << 5 // cell |
| << 1 << 1 // span |
| << 0 << 0 // scroll |
| << QAbstractItemView::PositionAtTop |
| << 4 << 4; // expected |
| } |
| |
| void tst_QTableView::scrollTo() |
| { |
| QFETCH(QAbstractItemView::ScrollMode, horizontalScrollMode); |
| QFETCH(QAbstractItemView::ScrollMode, 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(QAbstractItemView::ScrollHint, scrollHint); |
| QFETCH(int, expectedHorizontalScroll); |
| QFETCH(int, expectedVerticalScroll); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QWidget toplevel; |
| setFrameless(&toplevel); |
| QtTestTableView view(&toplevel); |
| |
| toplevel.show(); |
| // resizing to this size will ensure that there can ONLY_BE_ONE_CELL inside the view. |
| QSize forcedSize(columnWidth * 2, rowHeight * 2); |
| view.resize(forcedSize); |
| QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); |
| QTRY_COMPARE(view.size(), forcedSize); |
| |
| view.setModel(&model); |
| view.setSpan(row, column, rowSpan, columnSpan); |
| view.hideRow(hiddenRow); |
| view.hideColumn(hiddenColumn); |
| view.setHorizontalScrollMode(horizontalScrollMode); |
| view.setVerticalScrollMode(verticalScrollMode); |
| |
| for (int r = 0; r < rowCount; ++r) |
| view.setRowHeight(r, rowHeight); |
| for (int c = 0; c < columnCount; ++c) |
| view.setColumnWidth(c, columnWidth); |
| |
| view.horizontalScrollBar()->setValue(horizontalScroll); |
| view.verticalScrollBar()->setValue(verticalScroll); |
| |
| QModelIndex index = model.index(row, column); |
| QVERIFY(index.isValid()); |
| view.scrollTo(index, scrollHint); |
| QTRY_COMPARE(view.verticalScrollBar()->value(), expectedVerticalScroll); |
| QTRY_COMPARE(view.horizontalScrollBar()->value(), expectedHorizontalScroll); |
| } |
| |
| void tst_QTableView::indexAt_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| |
| QTest::addColumn<int>("rowHeight"); |
| QTest::addColumn<int>("columnWidth"); |
| |
| QTest::addColumn<int>("hiddenRow"); |
| QTest::addColumn<int>("hiddenColumn"); |
| |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| QTest::addColumn<int>("horizontalScroll"); |
| QTest::addColumn<int>("verticalScroll"); |
| QTest::addColumn<int>("x"); |
| QTest::addColumn<int>("y"); |
| QTest::addColumn<int>("expectedRow"); |
| QTest::addColumn<int>("expectedColumn"); |
| |
| QTest::newRow("no hidden, no span, no scroll, (20,20)") |
| << 10 << 10 // dim |
| << 40 << 40 // size |
| << -1 << -1 // hide |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 0 << 0 // scroll |
| << 20 << 20 // point |
| << 0 << 0; // expected |
| |
| QTest::newRow("row hidden, no span, no scroll, at (20,20)") |
| << 10 << 10 // dim |
| << 40 << 40 // size |
| << 0 << -1 // hide |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 0 << 0 // scroll |
| << 20 << 20 // point |
| << 1 << 0; // expected |
| |
| QTest::newRow("col hidden, no span, no scroll, at (20,20)") |
| << 10 << 10 // dim |
| << 40 << 40 // size |
| << -1 << 0 // hide |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 0 << 0 // scroll |
| << 20 << 20 // point |
| << 0 << 1; // expected |
| |
| QTest::newRow("no hidden, row span, no scroll, at (60,20)") |
| << 10 << 10 // dim |
| << 40 << 40 // size |
| << -1 << -1 // hide |
| << 0 << 0 // pos |
| << 2 << 1 // span |
| << 0 << 0 // scroll |
| << 20 << 60 // point |
| << 0 << 0; // expected |
| |
| |
| QTest::newRow("no hidden, col span, no scroll, at (60,20)") |
| << 10 << 10 // dim |
| << 40 << 40 // size |
| << -1 << -1 // hide |
| << 0 << 0 // pos |
| << 1 << 2 // span |
| << 0 << 0 // scroll |
| << 60 << 20 // point |
| << 0 << 0; // expected |
| |
| QTest::newRow("no hidden, no span, scroll (5,0), at (20,20)") |
| << 20 << 20 // dim |
| << 40 << 40 // size |
| << -1 << -1 // hide |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 5 << 0 // scroll |
| << 20 << 20 // point |
| << 0 << 5; // expected |
| |
| QTest::newRow("no hidden, no span, scroll (0,5), at (20,20)") |
| << 20 << 20 // dim |
| << 40 << 40 // size |
| << -1 << -1 // hide |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 0 << 5 // scroll |
| << 20 << 20 // point |
| << 5 << 0; // expected |
| |
| QTest::newRow("no hidden, no span, scroll (5,5), at (20,20)") |
| << 20 << 20 // dim |
| << 40 << 40 // size |
| << -1 << -1 // hide |
| << -1 << -1 // pos |
| << 1 << 1 // span |
| << 5 << 5 // scroll |
| << 20 << 20 // point |
| << 5 << 5; // expected |
| } |
| |
| void tst_QTableView::indexAt() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, rowHeight); |
| QFETCH(int, columnWidth); |
| QFETCH(int, hiddenRow); |
| QFETCH(int, hiddenColumn); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowSpan); |
| QFETCH(int, columnSpan); |
| QFETCH(int, horizontalScroll); |
| QFETCH(int, verticalScroll); |
| QFETCH(int, x); |
| QFETCH(int, y); |
| QFETCH(int, expectedRow); |
| QFETCH(int, expectedColumn); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QWidget toplevel; |
| QtTestTableView view(&toplevel); |
| |
| toplevel.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); |
| |
| //some styles change the scroll mode in their polish |
| view.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); |
| view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem); |
| |
| view.setModel(&model); |
| view.setSpan(row, column, rowSpan, columnSpan); |
| view.hideRow(hiddenRow); |
| view.hideColumn(hiddenColumn); |
| |
| for (int r = 0; r < rowCount; ++r) |
| view.setRowHeight(r, rowHeight); |
| for (int c = 0; c < columnCount; ++c) |
| view.setColumnWidth(c, columnWidth); |
| |
| view.horizontalScrollBar()->setValue(horizontalScroll); |
| view.verticalScrollBar()->setValue(verticalScroll); |
| |
| QModelIndex index = view.indexAt(QPoint(x, y)); |
| QTRY_COMPARE(index.row(), expectedRow); |
| QTRY_COMPARE(index.column(), expectedColumn); |
| } |
| |
| void tst_QTableView::span_data() |
| { |
| QTest::addColumn<int>("rowCount"); |
| QTest::addColumn<int>("columnCount"); |
| QTest::addColumn<int>("hiddenRow"); |
| QTest::addColumn<int>("hiddenColumn"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| QTest::addColumn<int>("expectedRowSpan"); |
| QTest::addColumn<int>("expectedColumnSpan"); |
| QTest::addColumn<bool>("clear"); |
| |
| QTest::newRow("top left 2x2") |
| << 10 << 10 |
| << -1 << -1 |
| << 0 << 0 |
| << 2 << 2 |
| << 2 << 2 |
| << false; |
| |
| QTest::newRow("top left 1x2") |
| << 10 << 10 |
| << 3 << 3 |
| << 0 << 0 |
| << 1 << 2 |
| << 1 << 2 |
| << false; |
| |
| QTest::newRow("top left 2x1") |
| << 10 << 10 |
| << -1 << -1 |
| << 0 << 0 |
| << 2 << 1 |
| << 2 << 1 |
| << false; |
| |
| /* This makes no sens. |
| QTest::newRow("top left 2x0") |
| << 10 << 10 |
| << -1 << -1 |
| << 0 << 0 |
| << 2 << 0 |
| << 2 << 0 |
| << false; |
| |
| QTest::newRow("top left 0x2") |
| << 10 << 10 |
| << -1 << -1 |
| << 0 << 0 |
| << 0 << 2 |
| << 0 << 2 |
| << false;*/ |
| |
| QTest::newRow("invalid 2x2") |
| << 10 << 10 |
| << -1 << -1 |
| << -1 << -1 |
| << 2 << 2 |
| << 1 << 1 |
| << false; |
| |
| QTest::newRow("top left 2x2") |
| << 10 << 10 |
| << -1 << -1 |
| << 0 << 0 |
| << 2 << 2 |
| << 2 << 2 |
| << false; |
| |
| QTest::newRow("bottom right 2x2") |
| << 10 << 10 |
| << -1 << -1 |
| << 8 << 8 |
| << 2 << 2 |
| << 2 << 2 |
| << false; |
| |
| QTest::newRow("invalid span 2x2") |
| << 10 << 10 |
| << -1 << -1 |
| << 8 << 8 |
| << 2 << 2 |
| << 2 << 2 |
| << false; |
| |
| QTest::newRow("invalid span 3x3") |
| << 10 << 10 |
| << -1 << -1 |
| << 6 << 6 |
| << 3 << 3 |
| << 2 << 3 |
| << true; |
| |
| } |
| |
| void tst_QTableView::span() |
| { |
| QFETCH(int, rowCount); |
| QFETCH(int, columnCount); |
| QFETCH(int, hiddenRow); |
| QFETCH(int, hiddenColumn); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowSpan); |
| QFETCH(int, columnSpan); |
| QFETCH(int, expectedRowSpan); |
| QFETCH(int, expectedColumnSpan); |
| QFETCH(bool, clear); |
| |
| QtTestTableModel model(rowCount, columnCount); |
| QtTestTableView view; |
| |
| view.setModel(&model); |
| view.show(); |
| |
| view.setSpan(row, column, rowSpan, columnSpan); |
| if (clear) { |
| model.removeLastRow(); |
| model.removeLastRow(); |
| view.update(); |
| } |
| |
| view.hideRow(hiddenRow); |
| view.hideColumn(hiddenColumn); |
| view.show(); |
| |
| QCOMPARE(view.rowSpan(row, column), expectedRowSpan); |
| QCOMPARE(view.columnSpan(row, column), expectedColumnSpan); |
| |
| if (hiddenRow > -1) { |
| QModelIndex hidden = model.index(hiddenRow, columnCount - 1); |
| QVERIFY(view.isIndexHidden(hidden)); |
| } |
| |
| if (hiddenColumn > -1) { |
| QModelIndex hidden = model.index(rowCount - 1, hiddenColumn); |
| QVERIFY(view.isIndexHidden(hidden)); |
| } |
| |
| view.clearSpans(); |
| QCOMPARE(view.rowSpan(row, column), 1); |
| QCOMPARE(view.columnSpan(row, column), 1); |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::spans_data() |
| { |
| QTest::addColumn<int>("rows"); |
| QTest::addColumn<int>("columns"); |
| QTest::addColumn<SpanList>("spans"); |
| QTest::addColumn<bool>("hideRowLastRowOfFirstSpan"); |
| QTest::addColumn<QPoint>("pos"); |
| QTest::addColumn<int>("expectedRowSpan"); |
| QTest::addColumn<int>("expectedColumnSpan"); |
| |
| QTest::newRow("1x3 span, query 3,0") |
| << 5 << 5 |
| << (SpanList() << QRect(3, 0, 1, 3)) |
| << false //no hidden row |
| << QPoint(3, 0) |
| << 1 |
| << 3; |
| |
| QTest::newRow("1x3 span, query 3,1") |
| << 5 << 5 |
| << (SpanList() << QRect(3, 0, 1, 3)) |
| << false //no hidden row |
| << QPoint(3, 1) |
| << 1 |
| << 3; |
| |
| QTest::newRow("1x3 span, query 3,2") |
| << 5 << 5 |
| << (SpanList() << QRect(3, 0, 1, 3)) |
| << false //no hidden row |
| << QPoint(3, 2) |
| << 1 |
| << 3; |
| |
| QTest::newRow("two 1x2 spans at the same column, query at 3,0") |
| << 5 << 5 |
| << (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2)) |
| << false //no hidden row |
| << QPoint(3, 0) |
| << 1 |
| << 2; |
| |
| QTest::newRow("two 1x2 spans at the same column, query at 4,0") |
| << 5 << 5 |
| << (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2)) |
| << false //no hidden row |
| << QPoint(4, 0) |
| << 1 |
| << 2; |
| |
| QTest::newRow("how to order spans (1,1)") |
| << 5 << 5 |
| << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
| << false //no hidden row |
| << QPoint(1, 1) |
| << 3 |
| << 1; |
| |
| QTest::newRow("how to order spans (2,1)") |
| << 5 << 5 |
| << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
| << false //no hidden row |
| << QPoint(2, 1) |
| << 3 |
| << 1; |
| |
| QTest::newRow("how to order spans (3,1)") |
| << 5 << 5 |
| << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
| << false //no hidden row |
| << QPoint(3, 1) |
| << 3 |
| << 1; |
| |
| QTest::newRow("how to order spans (1,2)") |
| << 5 << 5 |
| << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
| << false //no hidden row |
| << QPoint(1, 2) |
| << 2 |
| << 1; |
| |
| QTest::newRow("how to order spans (2,2)") |
| << 5 << 5 |
| << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
| << false //no hidden row |
| << QPoint(2, 2) |
| << 2 |
| << 1; |
| |
| QTest::newRow("spans with hidden rows") |
| << 3 << 2 |
| << (SpanList() << QRect(0, 0, 2, 2) << QRect(2, 0, 1, 2)) |
| << true //we hide the last row of the first span |
| << QPoint(2, 0) |
| << 1 |
| << 2; |
| |
| QTest::newRow("QTBUG-6004: No failing assertion, then it passes.") |
| << 5 << 5 |
| << (SpanList() << QRect(0, 0, 2, 2) << QRect(0, 0, 1, 1)) |
| << false |
| << QPoint(0, 0) |
| << 1 |
| << 1; |
| |
| QTest::newRow("QTBUG-6004 (follow-up): No failing assertion, then it passes.") |
| << 10 << 10 |
| << (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1)) |
| << false |
| << QPoint(0, 0) |
| << 1 |
| << 1; |
| |
| QTest::newRow("QTBUG-9631: remove one span") |
| << 10 << 10 |
| << (SpanList() << QRect(1, 1, 2, 1) << QRect(2, 2, 2, 2) << QRect(1, 1, 1, 1)) |
| << false |
| << QPoint(1, 1) |
| << 1 |
| << 1; |
| } |
| |
| void tst_QTableView::spans() |
| { |
| QFETCH(int, rows); |
| QFETCH(int, columns); |
| QFETCH(const 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 (const auto &sp : spans) |
| view.setSpan(sp.x(), sp.y(), sp.width(), sp.height()); |
| |
| if (hideRowLastRowOfFirstSpan) { |
| view.setRowHidden(spans.at(0).bottom(), true); |
| //we check that the span didn't break the visual rects of the model indexes |
| QRect first = view.visualRect( model.index(spans.at(0).top(), 0)); |
| QRect next = view.visualRect( model.index(spans.at(0).bottom() + 1, 0)); |
| QVERIFY(first.intersected(next).isEmpty()); |
| } |
| |
| QCOMPARE(view.columnSpan(pos.x(), pos.y()), expectedColumnSpan); |
| QCOMPARE(view.rowSpan(pos.x(), pos.y()), expectedRowSpan); |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::spansAfterRowInsertion() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QtTestTableModel model(10, 10); |
| QtTestTableView view; |
| view.setModel(&model); |
| view.setSpan(3, 3, 3, 3); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| |
| // Insertion before the span only shifts the span. |
| view.model()->insertRows(0, 2); |
| QCOMPARE(view.rowSpan(3, 3), 1); |
| QCOMPARE(view.columnSpan(3, 3), 1); |
| QCOMPARE(view.rowSpan(5, 3), 3); |
| QCOMPARE(view.columnSpan(5, 3), 3); |
| |
| // Insertion happens before the given row, so it only shifts the span also. |
| view.model()->insertRows(5, 2); |
| QCOMPARE(view.rowSpan(5, 3), 1); |
| QCOMPARE(view.columnSpan(5, 3), 1); |
| QCOMPARE(view.rowSpan(7, 3), 3); |
| QCOMPARE(view.columnSpan(7, 3), 3); |
| |
| // Insertion inside the span expands it. |
| view.model()->insertRows(8, 2); |
| QCOMPARE(view.rowSpan(7, 3), 5); |
| QCOMPARE(view.columnSpan(7, 3), 3); |
| |
| // Insertion after the span does nothing to it. |
| view.model()->insertRows(12, 2); |
| QCOMPARE(view.rowSpan(7, 3), 5); |
| QCOMPARE(view.columnSpan(7, 3), 3); |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::spansAfterColumnInsertion() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QtTestTableModel model(10, 10); |
| QtTestTableView view; |
| view.setModel(&model); |
| view.setSpan(3, 3, 3, 3); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| |
| // Insertion before the span only shifts the span. |
| view.model()->insertColumns(0, 2); |
| QCOMPARE(view.rowSpan(3, 3), 1); |
| QCOMPARE(view.columnSpan(3, 3), 1); |
| QCOMPARE(view.rowSpan(3, 5), 3); |
| QCOMPARE(view.columnSpan(3, 5), 3); |
| |
| // Insertion happens before the given column, so it only shifts the span also. |
| view.model()->insertColumns(5, 2); |
| QCOMPARE(view.rowSpan(3, 5), 1); |
| QCOMPARE(view.columnSpan(3, 5), 1); |
| QCOMPARE(view.rowSpan(3, 7), 3); |
| QCOMPARE(view.columnSpan(3, 7), 3); |
| |
| // Insertion inside the span expands it. |
| view.model()->insertColumns(8, 2); |
| QCOMPARE(view.rowSpan(3, 7), 3); |
| QCOMPARE(view.columnSpan(3, 7), 5); |
| |
| // Insertion after the span does nothing to it. |
| view.model()->insertColumns(12, 2); |
| QCOMPARE(view.rowSpan(3, 7), 3); |
| QCOMPARE(view.columnSpan(3, 7), 5); |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::spansAfterRowRemoval() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QtTestTableModel model(10, 10); |
| QtTestTableView view; |
| view.setModel(&model); |
| |
| static const QRect spans[] = { |
| {0, 1, 1, 2}, |
| {1, 2, 1, 2}, |
| {2, 2, 1, 5}, |
| {2, 8, 1, 2}, |
| {3, 4, 1, 2}, |
| {4, 4, 1, 4}, |
| {5, 6, 1, 3}, |
| {6, 7, 1, 3} |
| }; |
| for (const QRect &span : spans) |
| view.setSpan(span.top(), span.left(), span.height(), span.width()); |
| |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| view.model()->removeRows(3, 3); |
| |
| static const QRect expectedSpans[] = { |
| {0, 1, 1, 2}, |
| {1, 2, 1, 1}, |
| {2, 2, 1, 2}, |
| {2, 5, 1, 2}, |
| {3, 4, 1, 1}, |
| {4, 3, 1, 2}, |
| {5, 3, 1, 3}, |
| {6, 4, 1, 3} |
| }; |
| for (const QRect &span : expectedSpans) { |
| QCOMPARE(view.columnSpan(span.top(), span.left()), span.width()); |
| QCOMPARE(view.rowSpan(span.top(), span.left()), span.height()); |
| } |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::spansAfterColumnRemoval() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QtTestTableModel model(10, 10); |
| QtTestTableView view; |
| view.setModel(&model); |
| |
| // Same set as above just swapping columns and rows. |
| static const QRect spans[] = { |
| {0, 1, 1, 2}, |
| {1, 2, 1, 2}, |
| {2, 2, 1, 5}, |
| {2, 8, 1, 2}, |
| {3, 4, 1, 2}, |
| {4, 4, 1, 4}, |
| {5, 6, 1, 3}, |
| {6, 7, 1, 3} |
| }; |
| for (const QRect &span : spans) |
| view.setSpan(span.left(), span.top(), span.width(), span.height()); |
| |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| view.model()->removeColumns(3, 3); |
| |
| static const QRect expectedSpans[] = { |
| {0, 1, 1, 2}, |
| {1, 2, 1, 1}, |
| {2, 2, 1, 2}, |
| {2, 5, 1, 2}, |
| {3, 4, 1, 1}, |
| {4, 3, 1, 2}, |
| {5, 3, 1, 3}, |
| {6, 4, 1, 3} |
| }; |
| for (const QRect &span : expectedSpans) { |
| QCOMPARE(view.columnSpan(span.left(), span.top()), span.height()); |
| QCOMPARE(view.rowSpan(span.left(), span.top()), span.width()); |
| } |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::editSpanFromDirections_data() |
| { |
| QTest::addColumn<KeyList>("keyPresses"); |
| QTest::addColumn<QSharedPointer<QStandardItemModel>>("model"); |
| QTest::addColumn<int>("row"); |
| QTest::addColumn<int>("column"); |
| QTest::addColumn<int>("rowSpan"); |
| QTest::addColumn<int>("columnSpan"); |
| QTest::addColumn<QModelIndex>("expectedVisualCursorIndex"); |
| QTest::addColumn<QModelIndex>("expectedEditedIndex"); |
| |
| /* x = the cell that should be edited |
| c = the cell that should actually be the current index |
| +---+---+ |
| | | | |
| +---+---+ |
| | | x | |
| +---+ + |
| | | c | |
| +---+---+ |
| | | ^ | |
| +---+---+ */ |
| KeyList keyPresses {Qt::Key_Right, Qt::Key_PageDown, Qt::Key_Up}; |
| QSharedPointer<QStandardItemModel> model(new QStandardItemModel(4, 2)); |
| QTest::newRow("row span, bottom up") |
| << keyPresses << model << 1 << 1 << 2 << 1 << model->index(2, 1) << model->index(1, 1); |
| |
| /* +---+---+ |
| | | v | |
| +---+---+ |
| | |x,c| |
| +---+ + |
| | | | |
| +---+---+ |
| | | | |
| +---+---+ */ |
| keyPresses = {Qt::Key_Right, Qt::Key_Down}; |
| model = QSharedPointer<QStandardItemModel>::create(4, 2); |
| QTest::newRow("row span, top down") |
| << keyPresses << model << 1 << 1 << 2 << 1 << model->index(1, 1) << model->index(1, 1); |
| |
| /* +---+---+---+ |
| | | | | |
| +---+---+---+ |
| | |x,c| < | |
| +---+ +---+ |
| | | | | |
| +---+---+---+ */ |
| keyPresses = {Qt::Key_End, Qt::Key_Down, Qt::Key_Left}; |
| model = QSharedPointer<QStandardItemModel>::create(3, 3); |
| QTest::newRow("row span, right to left") |
| << keyPresses << model << 1 << 1 << 2 << 1 << model->index(1, 1) << model->index(1, 1); |
| |
| /* +---+---+---+ |
| | | | | |
| +---+---+---+ |
| | | x | | |
| +---+ +---+ |
| | > | c | | |
| +---+---+---+ */ |
| keyPresses = {Qt::Key_PageDown, Qt::Key_Right}; |
| model = QSharedPointer<QStandardItemModel>::create(3, 3); |
| QTest::newRow("row span, left to right") |
| << keyPresses << model << 1 << 1 << 2 << 1 << model->index(2, 1) << model->index(1, 1); |
| |
| /* +---+---+---+ |
| | | | | |
| +---+---+---+ |
| |x,c | |
| +---+---+---+ |
| | ^ | | | |
| +---+---+---+ */ |
| keyPresses = {Qt::Key_PageDown, Qt::Key_Up}; |
| model = QSharedPointer<QStandardItemModel>::create(3, 3); |
| QTest::newRow("col span, bottom up") |
| << keyPresses << model << 1 << 0 << 1 << 3 << model->index(1, 0) << model->index(1, 0); |
| |
| /* +---+---+---+ |
| | | | | |
| +---+---+---+ |
| | x c | |
| +---+---+---+ |
| | | ^ | | |
| +---+---+---+ */ |
| keyPresses = {Qt::Key_PageDown, Qt::Key_Right, Qt::Key_Up}; |
| model = QSharedPointer<QStandardItemModel>::create(3, 3); |
| QTest::newRow("col span, bottom up #2") |
| << keyPresses << model << 1 << 0 << 1 << 3 << model->index(1, 1) << model->index(1, 0); |
| |
| /* +---+---+---+ |
| | | | v | |
| +---+---+---+ |
| | x c | |
| +---+---+---+ |
| | | | | |
| +---+---+---+ */ |
| keyPresses = {Qt::Key_End, Qt::Key_Down}; |
| model = QSharedPointer<QStandardItemModel>::create(3, 3); |
| QTest::newRow("col span, top down") |
| << keyPresses << model << 1 << 0 << 1 << 3 << model->index(1, 2) << model->index(1, 0); |
| } |
| |
| class TableViewWithCursorExposed : public QTableView |
| { |
| public: |
| using QTableView::QTableView; |
| |
| QModelIndex visualCursorIndex() |
| { |
| QTableViewPrivate *d = static_cast<QTableViewPrivate*>(qt_widget_private(this)); |
| return d->model->index(d->visualCursor.y(), d->visualCursor.x()); |
| } |
| }; |
| |
| void tst_QTableView::editSpanFromDirections() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QFETCH(const KeyList, keyPresses); |
| QFETCH(QSharedPointer<QStandardItemModel>, model); |
| QFETCH(int, row); |
| QFETCH(int, column); |
| QFETCH(int, rowSpan); |
| QFETCH(int, columnSpan); |
| QFETCH(QModelIndex, expectedVisualCursorIndex); |
| QFETCH(QModelIndex, expectedEditedIndex); |
| |
| TableViewWithCursorExposed view; |
| view.setModel(model.data()); |
| // we have to make sure that PgUp/PgDown can scroll to the bottom/top |
| view.resize(view.horizontalHeader()->length() + 50, |
| view.verticalHeader()->length() + 50); |
| view.setSpan(row, column, rowSpan, columnSpan); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowActive(&view)); |
| |
| for (Qt::Key key : keyPresses) |
| QTest::keyClick(&view, key); |
| QCOMPARE(view.visualCursorIndex(), expectedVisualCursorIndex); |
| QCOMPARE(view.selectionModel()->currentIndex(), expectedEditedIndex); |
| |
| QTest::keyClick(&view, Qt::Key_X); |
| QTest::keyClick(QApplication::focusWidget(), Qt::Key_Enter); |
| QTRY_COMPARE(view.model()->data(expectedEditedIndex).toString(), QLatin1String("x")); |
| } |
| |
| class Model : public QAbstractTableModel |
| { |
| Q_OBJECT |
| public: |
| using QAbstractTableModel::QAbstractTableModel; |
| |
| int rowCount(const QModelIndex &) const override |
| { |
| return rows; |
| } |
| int columnCount(const QModelIndex &) const override |
| { |
| return columns; |
| } |
| QVariant data(const QModelIndex &, int) const override |
| { |
| return QVariant(); |
| } |
| void res() |
| { |
| beginResetModel(); |
| endResetModel(); |
| } |
| |
| int rows = 0; |
| int columns = 0; |
| }; |
| |
| 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({QLatin1String("one cell is enough")}); |
| view.setModel(&m); |
| |
| //setting the minimum height on the horizontal header |
| //and the minimum width on the vertical header |
| view.horizontalHeader()->setMinimumHeight(50); |
| view.verticalHeader()->setMinimumWidth(100); |
| |
| view.show(); |
| |
| QVERIFY( view.verticalHeader()->y() >= view.horizontalHeader()->minimumHeight()); |
| QVERIFY( view.horizontalHeader()->x() >= view.verticalHeader()->minimumWidth()); |
| } |
| |
| void tst_QTableView::resizeToContents() |
| { |
| //checks that the resize to contents is consistent |
| QTableWidget table(2,3); |
| QTableWidget table2(2,3); |
| QTableWidget table3(2,3); |
| |
| |
| table.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA")); |
| table2.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA")); |
| table3.setHorizontalHeaderItem(0, new QTableWidgetItem("A Lot of text here: BLA BLA BLA")); |
| table.horizontalHeader()->setVisible(false); |
| table2.horizontalHeader()->setVisible(false); |
| table.verticalHeader()->setVisible(false); |
| table2.verticalHeader()->setVisible(false); |
| |
| |
| for (int i = 0; i < table.columnCount(); i++) |
| table.resizeColumnToContents(i); |
| for (int i = 0; i < table.rowCount(); i++) |
| table.resizeRowToContents(i); |
| table2.resizeColumnsToContents(); |
| table2.resizeRowsToContents(); |
| table3.resizeColumnsToContents(); |
| table3.resizeRowsToContents(); |
| |
| //now let's check the row/col sizes |
| for (int i = 0; i < table.columnCount(); i++) { |
| QCOMPARE(table.columnWidth(i), table2.columnWidth(i)); |
| QCOMPARE(table2.columnWidth(i), table3.columnWidth(i)); |
| } |
| for (int i = 0; i < table.rowCount(); i++) { |
| QCOMPARE(table.rowHeight(i), table2.rowHeight(i)); |
| QCOMPARE(table2.rowHeight(i), table3.rowHeight(i)); |
| } |
| |
| } |
| |
| QT_BEGIN_NAMESPACE |
| extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp |
| QT_END_NAMESPACE |
| |
| void tst_QTableView::tabFocus() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| if (!qt_tab_all_widgets()) |
| QSKIP("This test requires full keyboard control to be enabled."); |
| |
| // QTableView enables tabKeyNavigation by default, but you should be able |
| // to change focus on an empty table view, or on a table view that doesn't |
| // have this property set. |
| QWidget window; |
| window.resize(200, 200); |
| |
| QTableView *view = new QTableView(&window); |
| QLineEdit *edit = new QLineEdit(&window); |
| |
| window.show(); |
| QApplication::setActiveWindow(&window); |
| window.setFocus(); |
| window.activateWindow(); |
| QVERIFY(QTest::qWaitForWindowActive(&window)); |
| |
| // window |
| QVERIFY(window.hasFocus()); |
| QVERIFY(!view->hasFocus()); |
| QVERIFY(!edit->hasFocus()); |
| |
| for (int i = 0; i < 2; ++i) { |
| // tab to view |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
| QTRY_VERIFY(!window.hasFocus()); |
| QVERIFY(view->hasFocus()); |
| QVERIFY(!edit->hasFocus()); |
| |
| // tab to edit |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
| QTRY_VERIFY(edit->hasFocus()); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(!view->hasFocus()); |
| } |
| |
| // backtab to view |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
| QTRY_VERIFY(view->hasFocus()); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(!edit->hasFocus()); |
| |
| // backtab to edit |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
| QTRY_VERIFY(edit->hasFocus()); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(!view->hasFocus()); |
| |
| QStandardItemModel model; |
| view->setModel(&model); |
| |
| // backtab to view |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
| QTRY_VERIFY(view->hasFocus()); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(!edit->hasFocus()); |
| |
| // backtab to edit |
| QTest::keyPress(QApplication::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(QApplication::focusWidget(), Qt::Key_Backtab); |
| QTRY_VERIFY(view->hasFocus()); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(!edit->hasFocus()); |
| |
| // backtab to edit doesn't work |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(view->hasFocus()); |
| QVERIFY(!edit->hasFocus()); |
| |
| view->setTabKeyNavigation(false); |
| |
| // backtab to edit |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Backtab); |
| QTRY_VERIFY(edit->hasFocus()); |
| QVERIFY(!window.hasFocus()); |
| QVERIFY(!view->hasFocus()); |
| |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
| QTRY_VERIFY(view->hasFocus()); |
| QTest::keyPress(QApplication::focusWidget(), Qt::Key_Tab); |
| QTRY_VERIFY(edit->hasFocus()); |
| } |
| |
| class BigModel : public QAbstractTableModel |
| { |
| Q_OBJECT |
| public: |
| QVariant data(const QModelIndex &index, |
| int role = Qt::DisplayRole) const override |
| { |
| if (role == Qt::DisplayRole) |
| return QString::number(index.column()) + QLatin1String(" - ") + QString::number(index.row()); |
| return QVariant(); |
| } |
| |
| int rowCount(const QModelIndex &parent = QModelIndex()) const override |
| { |
| Q_UNUSED(parent) |
| return 10000000; |
| } |
| |
| int columnCount(const QModelIndex &parent = QModelIndex()) const override |
| { |
| Q_UNUSED(parent) |
| return 20000000; |
| } |
| }; |
| |
| void tst_QTableView::bigModel() |
| { |
| //should not crash |
| QTableView view; |
| BigModel model; |
| view.setModel(&model); |
| view.show(); |
| view.setSpan(10002,10002,6,6); |
| QTest::qWait(100); |
| view.resize(1000,1000); |
| QTest::qWait(100); |
| view.scrollTo(model.index(10010,10010)); |
| QTest::qWait(100); |
| } |
| |
| void tst_QTableView::selectionSignal() |
| { |
| QtTestTableModel model(10, 10); |
| QtTestTableView view; |
| view.checkSignalOrder = true; |
| view.setModel(&model); |
| view.resize(200, 200); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| QTest::mouseClick(view.viewport(), Qt::LeftButton, {}, view.visualRect(model.index(2, 0)).center()); |
| } |
| |
| void tst_QTableView::setCurrentIndex() |
| { |
| QtTestTableModel model(4, 4); |
| QtTestTableView view; |
| view.setModel(&model); |
| |
| // submit() slot should be called in model when current row changes |
| view.setCurrentIndex(model.index(0,0)); |
| QCOMPARE(model.submit_count, 1); |
| view.setCurrentIndex(model.index(0,2)); |
| QCOMPARE(model.submit_count, 1); |
| view.setCurrentIndex(model.index(1,0)); |
| QCOMPARE(model.submit_count, 2); |
| view.setCurrentIndex(model.index(3,3)); |
| QCOMPARE(model.submit_count, 3); |
| view.setCurrentIndex(model.index(0,1)); |
| QCOMPARE(model.submit_count, 4); |
| view.setCurrentIndex(model.index(0,0)); |
| QCOMPARE(model.submit_count, 4); |
| } |
| |
| class task173773_EventFilter : public QObject |
| { |
| int paintEventCount_ = 0; |
| public: |
| using QObject::QObject; |
| int paintEventCount() const { return paintEventCount_; } |
| private: |
| bool eventFilter(QObject *obj, QEvent *e) override |
| { |
| Q_UNUSED(obj) |
| if (e->type() == QEvent::Paint) |
| ++paintEventCount_; |
| return false; |
| } |
| }; |
| |
| void tst_QTableView::task173773_updateVerticalHeader() |
| { |
| QStandardItemModel model(2, 1); |
| model.setData(model.index(0, 0), 0); |
| model.setData(model.index(1, 0), 1); |
| |
| QSortFilterProxyModel proxyModel; |
| proxyModel.setSourceModel(&model); |
| |
| QTableView view; |
| view.setModel(&proxyModel); |
| view.setSortingEnabled(true); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| |
| view.sortByColumn(0, Qt::AscendingOrder); |
| QTest::qWait(100); |
| |
| task173773_EventFilter eventFilter; |
| view.verticalHeader()->viewport()->installEventFilter(&eventFilter); |
| |
| view.sortByColumn(0, Qt::DescendingOrder); |
| QTest::qWait(100); |
| |
| // ### note: this test may occasionally pass even if the bug is present! |
| QVERIFY(eventFilter.paintEventCount() > 0); |
| } |
| |
| void tst_QTableView::task227953_setRootIndex() |
| { |
| QTableView tableView; |
| |
| //model = tree with two items with tables as children |
| QStandardItemModel model; |
| QStandardItem item1, item2; |
| model.appendColumn(QList<QStandardItem*>() << &item1 << &item2); |
| |
| |
| //setup the first table as a child of the first item |
| for ( int row = 0; row < 40; ++row ) { |
| item1.appendRow(QList<QStandardItem*>() << new QStandardItem(QLatin1String("row ") + QString::number(row))); |
| } |
| |
| //setup the second table as a child of the second item |
| for ( int row = 0; row < 10; ++row ) { |
| item2.appendRow(QList<QStandardItem*>() << new QStandardItem(QLatin1String("row ") + QString::number(row))); |
| } |
| |
| tableView.setModel(&model); |
| |
| //show the first 10 rows of the first table |
| QModelIndex root = model.indexFromItem(&item1); |
| tableView.setRootIndex(root); |
| for (int i = 10; i != 40; ++i) { |
| tableView.setRowHidden(i, true); |
| } |
| |
| QCOMPARE(tableView.verticalHeader()->count(), 40); |
| QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 30); |
| |
| //show the first 10 rows of the second table |
| tableView.setRootIndex(model.indexFromItem(&item2)); |
| |
| QCOMPARE(tableView.verticalHeader()->count(), 10); |
| QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 0); |
| QVERIFY(!tableView.verticalHeader()->isHidden()); |
| } |
| |
| void tst_QTableView::task240266_veryBigColumn() |
| { |
| QTableView table; |
| table.setFixedSize(500, 300); //just to make sure we have the 2 first columns visible |
| QStandardItemModel model(1, 3); |
| table.setModel(&model); |
| table.setColumnWidth(0, 100); //normal column |
| table.setColumnWidth(1, 100); //normal column |
| table.setColumnWidth(2, 9000); //very big column |
| table.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&table)); |
| |
| //some styles change the scroll mode in their polish |
| table.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); |
| table.setVerticalScrollMode(QAbstractItemView::ScrollPerItem); |
| |
| QScrollBar *scroll = table.horizontalScrollBar(); |
| QCOMPARE(scroll->minimum(), 0); |
| QCOMPARE(scroll->maximum(), model.columnCount() - 1); |
| QCOMPARE(scroll->singleStep(), 1); |
| |
| //1 is not always a very correct value for pageStep. Ideally this should be dynamic. |
| //Maybe something for Qt 5 ;-) |
| QCOMPARE(scroll->pageStep(), 1); |
| |
| } |
| |
| void tst_QTableView::task248688_autoScrollNavigation() |
| { |
| //we make sure that when navigating with the keyboard the view is correctly scrolled |
| //to the current item |
| QStandardItemModel model(16, 16); |
| QTableView view; |
| view.setModel(&model); |
| |
| view.hideColumn(8); |
| view.hideRow(8); |
| view.show(); |
| for (int r = 0; r < model.rowCount(); ++r) { |
| if (view.isRowHidden(r)) |
| continue; |
| for (int c = 0; c < model.columnCount(); ++c) { |
| if (view.isColumnHidden(c)) |
| continue; |
| QModelIndex index = model.index(r, c); |
| view.setCurrentIndex(index); |
| QVERIFY(view.viewport()->rect().contains(view.visualRect(index))); |
| } |
| } |
| } |
| |
| #if QT_CONFIG(wheelevent) |
| void tst_QTableView::mouseWheel_data() |
| { |
| QTest::addColumn<QAbstractItemView::ScrollMode>("scrollMode"); |
| QTest::addColumn<int>("delta"); |
| QTest::addColumn<int>("horizontalPositon"); |
| QTest::addColumn<int>("verticalPosition"); |
| |
| QTest::newRow("scroll up per item") |
| << QAbstractItemView::ScrollPerItem << 120 |
| << 10 - QApplication::wheelScrollLines() << 10 - QApplication::wheelScrollLines(); |
| QTest::newRow("scroll down per item") |
| << QAbstractItemView::ScrollPerItem << -120 |
| << 10 + QApplication::wheelScrollLines() << 10 + QApplication::wheelScrollLines(); |
| QTest::newRow("scroll down per pixel") |
| << QAbstractItemView::ScrollPerPixel << -120 |
| << 10 + QApplication::wheelScrollLines() * 91 << 10 + QApplication::wheelScrollLines() * 46; |
| } |
| |
| void tst_QTableView::mouseWheel() |
| { |
| QFETCH(QAbstractItemView::ScrollMode, scrollMode); |
| QFETCH(int, delta); |
| QFETCH(int, horizontalPositon); |
| QFETCH(int, verticalPosition); |
| |
| QtTestTableModel model(100, 100); |
| QWidget topLevel; |
| QtTestTableView view(&topLevel); |
| view.resize(500, 500); |
| topLevel.show(); |
| |
| QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); |
| |
| view.setModel(&model); |
| |
| for (int r = 0; r < 100; ++r) |
| view.setRowHeight(r, 50); |
| for (int c = 0; c < 100; ++c) |
| view.setColumnWidth(c, 100); |
| |
| view.setHorizontalScrollMode(scrollMode); |
| view.setVerticalScrollMode(scrollMode); |
| view.horizontalScrollBar()->setValue(10); |
| view.verticalScrollBar()->setValue(10); |
| |
| QPoint pos = view.viewport()->geometry().center(); |
| QWheelEvent verticalEvent(pos, view.mapToGlobal(pos), QPoint(), QPoint(0, delta), |
| Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); |
| QWheelEvent horizontalEvent(pos, view.mapToGlobal(pos), QPoint(), QPoint(delta, 0), |
| Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); |
| QApplication::sendEvent(view.viewport(), &horizontalEvent); |
| QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 15); |
| QApplication::sendEvent(view.viewport(), &verticalEvent); |
| QVERIFY(qAbs(view.verticalScrollBar()->value() - verticalPosition) < 15); |
| } |
| #endif // QT_CONFIG(wheelevent) |
| |
| void tst_QTableView::addColumnWhileEditing() |
| { |
| QTableView view; |
| QStandardItemModel model(1, 10); |
| view.setModel(&model); |
| QModelIndex last = model.index(0,9); |
| view.show(); |
| |
| view.openPersistentEditor(last); |
| view.scrollTo(last); |
| |
| //let's see if the editor is moved to the right location |
| //after adding a column |
| model.setColumnCount(model.columnCount() + 1); |
| QPointer<QLineEdit> editor = view.findChild<QLineEdit*>(); |
| QVERIFY(editor); |
| QCOMPARE(editor->geometry(), view.visualRect(last)); |
| |
| //let's see if the editor is moved to the right location |
| //after removing a column |
| view.scrollTo(model.index(0, model.columnCount()-1)); |
| model.setColumnCount(model.columnCount() - 1); |
| QVERIFY(editor); |
| QCOMPARE(editor->geometry(), view.visualRect(last)); |
| } |
| |
| void tst_QTableView::task259308_scrollVerticalHeaderSwappedSections() |
| { |
| QStandardItemModel model; |
| model.setRowCount(50); |
| model.setColumnCount(2); |
| for (int row = 0; row < model.rowCount(); ++row) |
| for (int col = 0; col < model.columnCount(); ++col) { |
| const QModelIndex &idx = model.index(row, col); |
| model.setData(idx, QVariant(row), Qt::EditRole); |
| } |
| |
| QTableView tv; |
| tv.setModel(&model); |
| tv.show(); |
| tv.verticalHeader()->swapSections(0, model.rowCount() - 1); |
| tv.setCurrentIndex(model.index(model.rowCount() - 1, 0)); |
| |
| QVERIFY(QTest::qWaitForWindowExposed(&tv)); |
| QTest::keyClick(&tv, Qt::Key_PageUp); // PageUp won't scroll when at top |
| QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0)); |
| |
| int newRow = tv.rowAt(tv.viewport()->height()); |
| QTest::keyClick(&tv, Qt::Key_PageDown); // Scroll down and check current |
| QTRY_COMPARE(tv.currentIndex().row(), newRow); |
| |
| tv.setCurrentIndex(model.index(0, 0)); |
| QTest::keyClick(&tv, Qt::Key_PageDown); // PageDown won't scroll when at the bottom |
| QTRY_COMPARE(tv.rowAt(tv.viewport()->height() - 1), tv.verticalHeader()->logicalIndex(model.rowCount() - 1)); |
| } |
| |
| template <typename T> |
| struct ValueSaver { |
| T &var, value; |
| ValueSaver(T &v) : var(v), value(v) { } |
| ~ValueSaver() { var = value; } |
| }; |
| |
| void tst_QTableView::task191545_dragSelectRows() |
| { |
| if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) |
| QSKIP("Wayland: This fails. Figure out why."); |
| |
| QStandardItemModel model(10, 10); |
| QTableView table; |
| table.setModel(&model); |
| table.setSelectionBehavior(QAbstractItemView::SelectItems); |
| table.setSelectionMode(QAbstractItemView::ExtendedSelection); |
| table.setMinimumSize(1000, 400); |
| table.show(); |
| QVERIFY(QTest::qWaitForWindowActive(&table)); |
| |
| ValueSaver<Qt::KeyboardModifiers> saver(QApplicationPrivate::modifier_buttons); |
| QApplicationPrivate::modifier_buttons = Qt::ControlModifier; |
| |
| { |
| QRect cellRect = table.visualRect(model.index(3, 0)); |
| QHeaderView *vHeader = table.verticalHeader(); |
| QWidget *vHeaderVp = vHeader->viewport(); |
| QPoint rowPos(cellRect.center()); |
| QMouseEvent rowPressEvent(QEvent::MouseButtonPress, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
| QCoreApplication::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); |
| QCoreApplication::sendEvent(vHeaderVp, &moveEvent); |
| } |
| QMouseEvent rowReleaseEvent(QEvent::MouseButtonRelease, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
| QCoreApplication::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); |
| QCoreApplication::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); |
| QCoreApplication::sendEvent(hHeaderVp, &moveEvent); |
| } |
| QMouseEvent colReleaseEvent(QEvent::MouseButtonRelease, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
| QCoreApplication::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); |
| QCoreApplication::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); |
| QCoreApplication::sendEvent(tableVp, &moveEvent); |
| } |
| QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
| QCoreApplication::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); |
| QCoreApplication::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); |
| QCoreApplication::sendEvent(tableVp, &moveEvent); |
| } |
| QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
| QCoreApplication::sendEvent(tableVp, &cellReleaseEvent); |
| |
| QTest::qWait(200); |
| for (int i = 0; i < 6; ++i) { |
| for (int j = 0; j < 6; ++j) { |
| QModelIndex index = model.index(3 + i, 3 + j, table.rootIndex()); |
| QVERIFY(!table.selectionModel()->isSelected(index)); |
| } |
| } |
| } |
| } |
| |
| void tst_QTableView::task234926_setHeaderSorting() |
| { |
| QStringListModel model; |
| QSortFilterProxyModel sfpm; // default QStandardItemModel does not support 'unsorted' state |
| sfpm.setSourceModel(&model); |
| const QStringList data({"orange", "apple", "banana", "lemon", "pumpkin"}); |
| QStringList sortedDataA = data; |
| QStringList sortedDataD = data; |
| std::sort(sortedDataA.begin(), sortedDataA.end()); |
| std::sort(sortedDataD.begin(), sortedDataD.end(), std::greater<QString>()); |
| model.setStringList(data); |
| QTableView view; |
| view.setModel(&sfpm); |
| |
| QTRY_COMPARE(model.stringList(), data); |
| view.setSortingEnabled(true); |
| view.sortByColumn(0, Qt::AscendingOrder); |
| for (int i = 0; i < sortedDataA.size(); ++i) |
| QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataA.at(i)); |
| |
| view.horizontalHeader()->setSortIndicator(0, Qt::DescendingOrder); |
| for (int i = 0; i < sortedDataD.size(); ++i) |
| QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataD.at(i)); |
| |
| QHeaderView *h = new QHeaderView(Qt::Horizontal); |
| h->setModel(&model); |
| view.setHorizontalHeader(h); |
| h->setSortIndicator(0, Qt::AscendingOrder); |
| for (int i = 0; i < sortedDataA.size(); ++i) |
| QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataA.at(i)); |
| |
| h->setSortIndicator(0, Qt::DescendingOrder); |
| for (int i = 0; i < sortedDataD.size(); ++i) |
| QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataD.at(i)); |
| |
| view.sortByColumn(-1, Qt::AscendingOrder); |
| QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), -1); |
| for (int i = 0; i < data.size(); ++i) |
| QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), data.at(i)); |
| } |
| |
| void tst_QTableView::taskQTBUG_5062_spansInconsistency() |
| { |
| const int nRows = 5; |
| const int nColumns = 5; |
| |
| QtTestTableModel model(nRows, nColumns); |
| QtTestTableView view; |
| view.setModel(&model); |
| |
| for (int i = 0; i < nRows; ++i) |
| view.setSpan(i, 0, 1, nColumns); |
| view.setSpan(2, 0, 1, 1); |
| view.setSpan(3, 0, 1, 1); |
| |
| VERIFY_SPANS_CONSISTENCY(&view); |
| } |
| |
| void tst_QTableView::taskQTBUG_4516_clickOnRichTextLabel() |
| { |
| QTableView view; |
| QStandardItemModel model(5,5); |
| view.setModel(&model); |
| QLabel label("rich text"); |
| label.setTextFormat(Qt::RichText); |
| view.setIndexWidget(model.index(1,1), &label); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| |
| view.setCurrentIndex(model.index(0,0)); |
| QCOMPARE(view.currentIndex(), model.index(0,0)); |
| |
| QTest::mouseClick(&label, Qt::LeftButton); |
| QCOMPARE(view.currentIndex(), model.index(1,1)); |
| } |
| |
| |
| void tst_QTableView::changeHeaderData() |
| { |
| QTableView view; |
| QStandardItemModel model(5,5); |
| view.setModel(&model); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| |
| QString text = "long long long text"; |
| const int textWidth = view.verticalHeader()->fontMetrics().horizontalAdvance(text); |
| QVERIFY(view.verticalHeader()->width() < textWidth); |
| |
| model.setHeaderData(2, Qt::Vertical, text); |
| |
| QTRY_VERIFY(view.verticalHeader()->width() > textWidth); |
| } |
| |
| #if QT_CONFIG(wheelevent) |
| void tst_QTableView::taskQTBUG_5237_wheelEventOnHeader() |
| { |
| QTableView view; |
| QStandardItemModel model(500,5); |
| view.setModel(&model); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| |
| int sbValueBefore = view.verticalScrollBar()->value(); |
| QHeaderView *header = view.verticalHeader(); |
| QTest::mouseMove(header); |
| QPoint pos = header->geometry().center(); |
| QWheelEvent wheelEvent(pos, header->viewport()->mapToGlobal(pos), QPoint(), QPoint(0, -720), |
| Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); |
| QApplication::sendEvent(header->viewport(), &wheelEvent); |
| int sbValueAfter = view.verticalScrollBar()->value(); |
| QVERIFY(sbValueBefore != sbValueAfter); |
| } |
| #endif |
| |
| class TestTableView : public QTableView |
| { |
| Q_OBJECT |
| public: |
| TestTableView(QWidget *parent = nullptr) : QTableView(parent) |
| { |
| connect(this, &QTableView::entered, this, &TestTableView::openPersistentEditor); |
| } |
| public slots: |
| void onDataChanged() |
| { |
| for (int i = 0; i < model()->rowCount(); i++) { |
| setRowHidden(i, model()->data(model()->index(i, 0)).toBool()); |
| } |
| } |
| }; |
| |
| |
| void tst_QTableView::taskQTBUG_8585_crashForNoGoodReason() |
| { |
| QStandardItemModel model; |
| model.insertColumn(0, QModelIndex()); |
| for (int i = 0; i < 20; i++) |
| model.insertRow(i); |
| |
| TestTableView w; |
| w.setMouseTracking(true); |
| w.setModel(&model); |
| connect(&model, &QStandardItemModel::dataChanged, &w, &TestTableView::onDataChanged); |
| w.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&w)); |
| for (int i = 0; i < 10; i++) |
| { |
| QTest::mouseMove(w.viewport(), QPoint(50, 20)); |
| w.model()->setData(w.indexAt(QPoint(50, 20)), true); |
| QTest::mouseMove(w.viewport(), QPoint(50, 25)); |
| } |
| } |
| |
| class TableView7774 : public QTableView |
| { |
| public: |
| using QTableView::visualRegionForSelection; |
| }; |
| |
| void tst_QTableView::taskQTBUG_7774_RtoLVisualRegionForSelection() |
| { |
| TableView7774 view; |
| QStandardItemModel model(5,5); |
| view.setModel(&model); |
| view.setLayoutDirection(Qt::RightToLeft); |
| view.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&view)); |
| |
| QItemSelectionRange range(model.index(2, 0), model.index(2, model.columnCount() - 1)); |
| QItemSelection selection; |
| selection << range; |
| QRegion region = view.visualRegionForSelection(selection); |
| QVERIFY(!region.isEmpty()); |
| QCOMPARE(region.begin()[0], view.visualRect(range.topLeft()) | view.visualRect(range.bottomRight())); |
| } |
| |
| void tst_QTableView::taskQTBUG_8777_scrollToSpans() |
| { |
| QTableWidget table(75,5); |
| for (int i=0; i<50; i++) |
| table.setSpan(2+i, 0, 1, 5); |
| table.setCurrentCell(0,2); |
| table.show(); |
| |
| for (int i = 0; i < 45; ++i) |
| QTest::keyClick(&table, Qt::Key_Down); |
| |
| QVERIFY(table.verticalScrollBar()->value() > 10); |
| } |
| |
| void tst_QTableView::taskQTBUG_10169_sizeHintForRow() |
| { |
| QtTestTableView tableView; |
| QStandardItemModel model(1, 3); |
| model.setData(model.index(0, 0), "Word wrapping text goes here."); |
| tableView.setModel(&model); |
| tableView.verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); |
| const int orderedHeight = tableView.sizeHintForRow(0); |
| tableView.horizontalHeader()->moveSection(2, 0); |
| const int reorderedHeight = tableView.sizeHintForRow(0); |
| |
| //the order of the columns shouldn't matter. |
| QCOMPARE(orderedHeight, reorderedHeight); |
| } |
| |
| void tst_QTableView::viewOptions() |
| { |
| QtTestTableView view; |
| QStyleOptionViewItem options = view.viewOptions(); |
| QVERIFY(options.showDecorationSelected); |
| } |
| |
| void tst_QTableView::taskQTBUG_30653_doItemsLayout() |
| { |
| QWidget topLevel; |
| QtTestTableView view(&topLevel); |
| |
| QtTestTableModel model(5, 5); |
| view.setModel(&model); |
| |
| QtTestItemDelegate delegate; |
| delegate.hint = QSize(50, 50); |
| view.setItemDelegate(&delegate); |
| |
| view.resizeRowsToContents(); |
| view.resizeColumnsToContents(); |
| |
| // show two and half rows/cols |
| int extraWidth = view.verticalHeader()->sizeHint().width() + view.verticalScrollBar()->sizeHint().width(); |
| int extraHeight = view.horizontalHeader()->sizeHint().height() + view.horizontalScrollBar()->sizeHint().height(); |
| view.resize(125 + extraWidth, 125 + extraHeight); |
| |
| topLevel.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); |
| |
| // the offset after scrollToBottom() and doItemsLayout() should not differ |
| // as the view content should stay aligned to the last section |
| view.scrollToBottom(); |
| int scrollToBottomOffset = view.verticalHeader()->offset(); |
| view.doItemsLayout(); |
| int doItemsLayoutOffset = view.verticalHeader()->offset(); |
| |
| QCOMPARE(scrollToBottomOffset, doItemsLayoutOffset); |
| } |
| |
| void tst_QTableView::taskQTBUG_7232_AllowUserToControlSingleStep() |
| { |
| // When we set the scrollMode to ScrollPerPixel it will adjust the scrollbars singleStep automatically |
| // Setting a singlestep on a scrollbar should however imply that the user takes control (and it is not changed by geometry updates). |
| // Setting a singlestep to -1 return to an automatic control of the singleStep. |
| QTableView t; |
| t.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); |
| t.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); |
| QStandardItemModel model(200, 200); |
| t.setModel(&model); |
| t.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&t)); |
| t.setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); |
| t.setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); |
| |
| t.setGeometry(200, 200, 200, 200); |
| int vStep1 = t.verticalScrollBar()->singleStep(); |
| int hStep1 = t.horizontalScrollBar()->singleStep(); |
| QVERIFY(vStep1 > 1); |
| QVERIFY(hStep1 > 1); |
| |
| t.verticalScrollBar()->setSingleStep(1); |
| t.setGeometry(300, 300, 300, 300); |
| QCOMPARE(t.verticalScrollBar()->singleStep(), 1); |
| |
| t.horizontalScrollBar()->setSingleStep(1); |
| t.setGeometry(400, 400, 400, 400); |
| QCOMPARE(t.horizontalScrollBar()->singleStep(), 1); |
| |
| t.setGeometry(200, 200, 200, 200); |
| t.verticalScrollBar()->setSingleStep(-1); |
| t.horizontalScrollBar()->setSingleStep(-1); |
| QCOMPARE(vStep1, t.verticalScrollBar()->singleStep()); |
| QCOMPARE(hStep1, t.horizontalScrollBar()->singleStep()); |
| } |
| |
| void tst_QTableView::taskQTBUG_50171_selectRowAfterSwapColumns() |
| { |
| { |
| QtTestTableView tableView; |
| QtTestTableModel model(2, 3); |
| tableView.setModel(&model); |
| |
| tableView.horizontalHeader()->swapSections(1, 2); |
| tableView.horizontalHeader()->hideSection(0); |
| tableView.selectRow(1); |
| |
| QItemSelectionModel* tableSelectionModel = tableView.selectionModel(); |
| QCOMPARE(tableSelectionModel->isRowSelected(1, QModelIndex()), true); |
| QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 0)), false); |
| QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 1)), false); |
| QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 2)), false); |
| } |
| |
| { |
| QtTestTableView tableView; |
| QtTestTableModel model(3, 2); |
| tableView.setModel(&model); |
| |
| tableView.verticalHeader()->swapSections(1, 2); |
| tableView.verticalHeader()->hideSection(0); |
| tableView.selectColumn(1); |
| |
| QItemSelectionModel* sModel = tableView.selectionModel(); |
| QCOMPARE(sModel->isColumnSelected(1, QModelIndex()), true); |
| QCOMPARE(sModel->isSelected(tableView.model()->index(0, 0)), false); |
| QCOMPARE(sModel->isSelected(tableView.model()->index(1, 0)), false); |
| QCOMPARE(sModel->isSelected(tableView.model()->index(2, 0)), false); |
| } |
| } |
| |
| class DeselectTableWidget : public QTableWidget |
| { |
| public: |
| using QTableWidget::QTableWidget; |
| QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &, |
| const QEvent * = nullptr) const override |
| { |
| return QItemSelectionModel::Toggle; |
| } |
| }; |
| |
| void tst_QTableView::deselectRow() |
| { |
| DeselectTableWidget tw(20, 20); |
| tw.show(); |
| QVERIFY(QTest::qWaitForWindowExposed(&tw)); |
| tw.hideColumn(0); |
| QVERIFY(tw.isColumnHidden(0)); |
| tw.selectRow(1); |
| QVERIFY(tw.selectionModel()->isRowSelected(1, QModelIndex())); |
| tw.selectRow(1); |
| // QTBUG-79092 - deselection was not possible when column 0 was hidden |
| QVERIFY(!tw.selectionModel()->isRowSelected(1, QModelIndex())); |
| } |
| |
| // This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel |
| #if QT_CONFIG(textmarkdownwriter) |
| |
| // #define DEBUG_WRITE_OUTPUT |
| |
| void tst_QTableView::markdownWriter() |
| { |
| QtTestTableModel model(2, 3); |
| QString md; |
| { |
| QTextStream stream(&md); |
| QTextMarkdownWriter writer(stream, QTextDocument::MarkdownDialectGitHub); |
| writer.writeTable(&model); |
| } |
| |
| #ifdef DEBUG_WRITE_OUTPUT |
| { |
| QFile out("/tmp/table.md"); |
| out.open(QFile::WriteOnly); |
| out.write(md.toUtf8()); |
| out.close(); |
| } |
| #endif |
| |
| QCOMPARE(md, QString::fromLatin1("|1 |2 |3 |\n|-------|-------|-------|\n|[0,0,0]|[0,1,0]|[0,2,0]|\n|[1,0,0]|[1,1,0]|[1,2,0]|\n")); |
| } |
| #endif |
| |
| QTEST_MAIN(tst_QTableView) |
| #include "tst_qtableview.moc" |