summaryrefslogtreecommitdiffstats
path: root/tests/auto/qlistview/tst_qlistview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qlistview/tst_qlistview.cpp')
-rw-r--r--tests/auto/qlistview/tst_qlistview.cpp1522
1 files changed, 1522 insertions, 0 deletions
diff --git a/tests/auto/qlistview/tst_qlistview.cpp b/tests/auto/qlistview/tst_qlistview.cpp
new file mode 100644
index 0000000..5cada02
--- /dev/null
+++ b/tests/auto/qlistview/tst_qlistview.cpp
@@ -0,0 +1,1522 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+
+#include <qabstractitemmodel.h>
+#include <qapplication.h>
+#include <qlistview.h>
+#include <qitemdelegate.h>
+#include <qstandarditemmodel.h>
+#include <qstringlistmodel.h>
+#include <cmath>
+#include <math.h>
+#include <QtGui/QScrollBar>
+#include <QtGui/QDialog>
+#if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
+#include <windows.h>
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class tst_QListView : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QListView();
+ virtual ~tst_QListView();
+
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+private slots:
+ void getSetCheck();
+ void noDelegate();
+ void noModel();
+ void emptyModel();
+ void removeRows();
+ void cursorMove();
+ void hideRows();
+ void moveCursor();
+ void moveCursor2();
+ void moveCursor3();
+ void indexAt();
+ void clicked();
+ void singleSelectionRemoveRow();
+ void singleSelectionRemoveColumn();
+ void modelColumn();
+ void hideFirstRow();
+ void batchedMode();
+ void setCurrentIndex();
+ void selection_data();
+ void selection();
+ void scrollTo();
+ void scrollBarRanges();
+ void scrollBarAsNeeded_data();
+ void scrollBarAsNeeded();
+ void moveItems();
+ void wordWrap();
+ void setCurrentIndexAfterAppendRowCrash();
+ void emptyItemSize();
+ void task203585_selectAll();
+ void task228566_infiniteRelayout();
+};
+
+// Testing get/set functions
+void tst_QListView::getSetCheck()
+{
+ QListView obj1;
+ // Movement QListView::movement()
+ // void QListView::setMovement(Movement)
+ obj1.setMovement(QListView::Movement(QListView::Static));
+ QCOMPARE(QListView::Movement(QListView::Static), obj1.movement());
+ obj1.setMovement(QListView::Movement(QListView::Free));
+ QCOMPARE(QListView::Movement(QListView::Free), obj1.movement());
+ obj1.setMovement(QListView::Movement(QListView::Snap));
+ QCOMPARE(QListView::Movement(QListView::Snap), obj1.movement());
+
+ // Flow QListView::flow()
+ // void QListView::setFlow(Flow)
+ obj1.setFlow(QListView::Flow(QListView::LeftToRight));
+ QCOMPARE(QListView::Flow(QListView::LeftToRight), obj1.flow());
+ obj1.setFlow(QListView::Flow(QListView::TopToBottom));
+ QCOMPARE(QListView::Flow(QListView::TopToBottom), obj1.flow());
+
+ // ResizeMode QListView::resizeMode()
+ // void QListView::setResizeMode(ResizeMode)
+ obj1.setResizeMode(QListView::ResizeMode(QListView::Fixed));
+ QCOMPARE(QListView::ResizeMode(QListView::Fixed), obj1.resizeMode());
+ obj1.setResizeMode(QListView::ResizeMode(QListView::Adjust));
+ QCOMPARE(QListView::ResizeMode(QListView::Adjust), obj1.resizeMode());
+
+ // LayoutMode QListView::layoutMode()
+ // void QListView::setLayoutMode(LayoutMode)
+ obj1.setLayoutMode(QListView::LayoutMode(QListView::SinglePass));
+ QCOMPARE(QListView::LayoutMode(QListView::SinglePass), obj1.layoutMode());
+ obj1.setLayoutMode(QListView::LayoutMode(QListView::Batched));
+ QCOMPARE(QListView::LayoutMode(QListView::Batched), obj1.layoutMode());
+
+ // int QListView::spacing()
+ // void QListView::setSpacing(int)
+ obj1.setSpacing(0);
+ QCOMPARE(0, obj1.spacing());
+ obj1.setSpacing(INT_MIN);
+ QCOMPARE(INT_MIN, obj1.spacing());
+ obj1.setSpacing(INT_MAX);
+ QCOMPARE(INT_MAX, obj1.spacing());
+
+ // ViewMode QListView::viewMode()
+ // void QListView::setViewMode(ViewMode)
+ obj1.setViewMode(QListView::ViewMode(QListView::ListMode));
+ QCOMPARE(QListView::ViewMode(QListView::ListMode), obj1.viewMode());
+ obj1.setViewMode(QListView::ViewMode(QListView::IconMode));
+ QCOMPARE(QListView::ViewMode(QListView::IconMode), obj1.viewMode());
+
+ // int QListView::modelColumn()
+ // void QListView::setModelColumn(int)
+ obj1.setModelColumn(0);
+ QCOMPARE(0, obj1.modelColumn());
+ obj1.setModelColumn(INT_MIN);
+ QCOMPARE(0, obj1.modelColumn()); // Less than 0 => 0
+ obj1.setModelColumn(INT_MAX);
+ QCOMPARE(0, obj1.modelColumn()); // No model => 0
+
+ // bool QListView::uniformItemSizes()
+ // void QListView::setUniformItemSizes(bool)
+ obj1.setUniformItemSizes(false);
+ QCOMPARE(false, obj1.uniformItemSizes());
+ obj1.setUniformItemSizes(true);
+ QCOMPARE(true, obj1.uniformItemSizes());
+
+ // make sure setViewMode() doesn't reset resizeMode
+ obj1.clearPropertyFlags();
+ obj1.setResizeMode(QListView::Adjust);
+ obj1.setViewMode(QListView::IconMode);
+ QCOMPARE(obj1.resizeMode(), QListView::Adjust);
+
+ obj1.setWordWrap(false);
+ QCOMPARE(false, obj1.wordWrap());
+ obj1.setWordWrap(true);
+ QCOMPARE(true, obj1. wordWrap());
+}
+
+class QtTestModel: public QAbstractListModel
+{
+public:
+ QtTestModel(QObject *parent = 0): QAbstractListModel(parent),
+ colCount(0), rCount(0), wrongIndex(false) {}
+ int rowCount(const QModelIndex&) const { return rCount; }
+ int columnCount(const QModelIndex&) const { return colCount; }
+ bool isEditable(const QModelIndex &) const { return true; }
+
+ QVariant data(const QModelIndex &idx, int role) const
+ {
+
+ if (!m_icon.isNull() && role == Qt::DecorationRole) {
+ return m_icon;
+ }
+ if (role != Qt::DisplayRole)
+ return QVariant();
+
+ if (idx.row() < 0 || idx.column() < 0 || idx.column() >= colCount
+ || idx.row() >= rCount) {
+ wrongIndex = true;
+ qWarning("got invalid modelIndex %d/%d", idx.row(), idx.column());
+ }
+ return QString("%1/%2").arg(idx.row()).arg(idx.column());
+ }
+
+ void removeLastRow()
+ {
+ beginRemoveRows(QModelIndex(), rCount - 2, rCount - 1);
+ --rCount;
+ endRemoveRows();
+ }
+
+ void removeAllRows()
+ {
+ beginRemoveRows(QModelIndex(), 0, rCount - 1);
+ rCount = 0;
+ endRemoveRows();
+ }
+
+ void setDataIcon(const QIcon &icon)
+ {
+ m_icon = icon;
+ }
+
+ int colCount, rCount;
+ QIcon m_icon;
+ mutable bool wrongIndex;
+};
+
+tst_QListView::tst_QListView()
+{
+}
+
+tst_QListView::~tst_QListView()
+{
+}
+
+void tst_QListView::initTestCase()
+{
+}
+
+void tst_QListView::cleanupTestCase()
+{
+}
+
+void tst_QListView::init()
+{
+#ifdef Q_OS_WINCE //disable magic for WindowsCE
+ qApp->setAutoMaximizeThreshold(-1);
+#endif
+}
+
+void tst_QListView::cleanup()
+{
+}
+
+
+void tst_QListView::noDelegate()
+{
+ QtTestModel model(0);
+ model.rCount = model.colCount = 10;
+ QListView view;
+ view.setModel(&model);
+ view.setItemDelegate(0);
+ view.show();
+}
+
+void tst_QListView::noModel()
+{
+ QListView view;
+ view.show();
+ view.setRowHidden(0, true);
+}
+
+void tst_QListView::emptyModel()
+{
+ QtTestModel model(0);
+ QListView view;
+ view.setModel(&model);
+ view.show();
+ QVERIFY(!model.wrongIndex);
+}
+
+void tst_QListView::removeRows()
+{
+ QtTestModel model(0);
+ model.rCount = model.colCount = 10;
+
+ QListView view;
+ view.setModel(&model);
+ view.show();
+
+ model.removeLastRow();
+ QVERIFY(!model.wrongIndex);
+
+ model.removeAllRows();
+ QVERIFY(!model.wrongIndex);
+}
+
+void tst_QListView::cursorMove()
+{
+ int rows = 6*6;
+ int columns = 6;
+
+ QStandardItemModel model(rows, columns);
+ QListView view;
+ view.setModel(&model);
+
+ for (int j = 0; j < columns; ++j) {
+ view.setModelColumn(j);
+ for (int i = 0; i < rows; ++i) {
+ QModelIndex index = model.index(i, j);
+ model.setData(index, QString("[%1,%2]").arg(i).arg(j));
+ view.setCurrentIndex(index);
+ QApplication::processEvents();
+ QCOMPARE(view.currentIndex(), index);
+ }
+ }
+
+ QSize cellsize(60, 25);
+ int gap = 1; // compensate for the scrollbars
+ int displayColumns = 6;
+
+ view.resize((displayColumns + gap) * cellsize.width(),
+ int((ceil(double(rows) / displayColumns) + gap) * cellsize.height()));
+ view.setResizeMode(QListView::Adjust);
+ view.setGridSize(cellsize);
+ view.setViewMode(QListView::IconMode);
+ view.doItemsLayout();
+ view.show();
+
+ QVector<Qt::Key> keymoves;
+ keymoves << 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;
+
+ int displayRow = rows / displayColumns - 1;
+ int displayColumn = displayColumns - (rows % displayColumns) - 1;
+
+ QApplication::instance()->processEvents();
+ for (int i = 0; i < keymoves.size(); ++i) {
+ Qt::Key key = keymoves.at(i);
+ QTest::keyClick(&view, key);
+ switch (key) {
+ case Qt::Key_Up:
+ displayRow = qMax(0, displayRow - 1);
+ break;
+ case Qt::Key_Down:
+ displayRow = qMin(rows / displayColumns - 1, displayRow + 1);
+ break;
+ case Qt::Key_Left:
+ displayColumn = qMax(0, displayColumn - 1);
+ break;
+ case Qt::Key_Right:
+ displayColumn = qMin(displayColumns-1, displayColumn + 1);
+ break;
+ default:
+ QVERIFY(false);
+ }
+
+ QApplication::instance()->processEvents();
+
+ int row = displayRow * displayColumns + displayColumn;
+ int column = columns - 1;
+ QModelIndex index = model.index(row, column);
+ QCOMPARE(view.currentIndex().row(), row);
+ QCOMPARE(view.currentIndex().column(), column);
+ QCOMPARE(view.currentIndex(), index);
+ }
+}
+
+void tst_QListView::hideRows()
+{
+ QtTestModel model(0);
+ model.rCount = model.colCount = 10;
+
+ QListView view;
+ view.setModel(&model);
+ view.show();
+
+ // hide then show
+ QVERIFY(!view.isRowHidden(2));
+ view.setRowHidden(2, true);
+ QVERIFY(view.isRowHidden(2));
+ view.setRowHidden(2, false);
+ QVERIFY(!view.isRowHidden(2));
+
+ // re show same row
+ QVERIFY(!view.isRowHidden(2));
+ view.setRowHidden(2, false);
+ QVERIFY(!view.isRowHidden(2));
+
+ // double hidding
+ QVERIFY(!view.isRowHidden(2));
+ view.setRowHidden(2, true);
+ QVERIFY(view.isRowHidden(2));
+ view.setRowHidden(2, true);
+ QVERIFY(view.isRowHidden(2));
+ view.setRowHidden(2, false);
+ QVERIFY(!view.isRowHidden(2));
+
+ // show in per-item mode, then hide the first row
+ view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
+ QVERIFY(!view.isRowHidden(0));
+ view.setRowHidden(0, true);
+ QVERIFY(view.isRowHidden(0));
+ view.setRowHidden(0, false);
+ QVERIFY(!view.isRowHidden(0));
+
+}
+
+
+void tst_QListView::moveCursor()
+{
+ QtTestModel model(0);
+ model.rCount = model.colCount = 10;
+
+ QListView view;
+ view.setModel(&model);
+
+ QTest::keyClick(&view, Qt::Key_Down);
+
+ view.setModel(0);
+ view.setModel(&model);
+ view.setRowHidden(0, true);
+
+ QTest::keyClick(&view, Qt::Key_Down);
+ QCOMPARE(view.selectionModel()->currentIndex(), model.index(1, 0));
+}
+
+class QMoveCursorListView : public QListView
+{
+public:
+ QMoveCursorListView() : QListView() {}
+
+ enum CursorAction { MoveUp, MoveDown, MoveLeft, MoveRight,
+ MoveHome, MoveEnd, MovePageUp, MovePageDown,
+ MoveNext, MovePrevious };
+
+ QModelIndex moveCursor(QMoveCursorListView::CursorAction action, Qt::KeyboardModifiers modifiers)
+ {
+ return QListView::moveCursor((QListView::CursorAction)action, modifiers);
+ }
+};
+
+void tst_QListView::moveCursor2()
+{
+ QtTestModel model(0);
+ model.colCount = 1;
+ model.rCount = 100;
+ QPixmap pm(32, 32);
+ pm.fill(Qt::green);
+ model.setDataIcon(QIcon(pm));
+
+ QMoveCursorListView vu;
+ vu.setModel(&model);
+ vu.setIconSize(QSize(36,48));
+ vu.setGridSize(QSize(34,56));
+ //Standard framesize is 1. If Framesize > 2 increase size
+ int frameSize = qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ vu.resize(300 + frameSize * 2,300);
+ vu.setFlow(QListView::LeftToRight);
+ vu.setMovement(QListView::Static);
+ vu.setWrapping(true);
+ vu.setViewMode(QListView::IconMode);
+ vu.setLayoutMode(QListView::Batched);
+ vu.show();
+ vu.selectionModel()->setCurrentIndex(model.index(0,0), QItemSelectionModel::SelectCurrent);
+ QCoreApplication::processEvents();
+
+ QModelIndex idx = vu.moveCursor(QMoveCursorListView::MoveHome, Qt::NoModifier);
+ QCOMPARE(idx, model.index(0,0));
+ idx = vu.moveCursor(QMoveCursorListView::MoveDown, Qt::NoModifier);
+ QModelIndex p = model.index(8,0);
+ QCOMPARE(idx, model.index(8,0));
+
+}
+
+void tst_QListView::moveCursor3()
+{
+ //this tests is for task 159792
+ //it tests that navigation works even with non uniform item sizes
+ QListView view;
+ QStandardItemModel model(0, 1);
+ QStandardItem *i1 = new QStandardItem("First item, long name");
+ QStandardItem *i2 = new QStandardItem("2nd item");
+ QStandardItem *i3 = new QStandardItem("Third item, long name");
+ i1->setSizeHint(QSize(200,32));
+ model.appendRow(i1);
+ model.appendRow(i2);
+ model.appendRow(i3);
+ view.setModel(&model);
+
+ view.setCurrentIndex(model.index(0, 0));
+
+ QCOMPARE(view.selectionModel()->currentIndex(), model.index(0, 0));
+ QTest::keyClick(&view, Qt::Key_Down);
+ QCOMPARE(view.selectionModel()->currentIndex(), model.index(1, 0));
+ QTest::keyClick(&view, Qt::Key_Down);
+ QCOMPARE(view.selectionModel()->currentIndex(), model.index(2, 0));
+ QTest::keyClick(&view, Qt::Key_Up);
+ QCOMPARE(view.selectionModel()->currentIndex(), model.index(1, 0));
+ QTest::keyClick(&view, Qt::Key_Up);
+ QCOMPARE(view.selectionModel()->currentIndex(), model.index(0, 0));
+}
+
+
+class QListViewShowEventListener : public QListView
+{
+public:
+ QListViewShowEventListener() : QListView() { m_shown = false;}
+
+ virtual void showEvent(QShowEvent * /*e*/)
+ {
+ int columnwidth = sizeHintForColumn(0);
+ QSize sz = sizeHintForIndex(model()->index(0,0));
+
+ // This should retrieve a model index in the 2nd section
+ m_index = indexAt(QPoint(columnwidth +2, sz.height()/2));
+ m_shown = true;
+ }
+
+ QModelIndex m_index;
+ bool m_shown;
+
+};
+
+void tst_QListView::indexAt()
+{
+ QtTestModel model(0);
+ model.rCount = 2;
+ model.colCount = 1;
+
+ QListView view;
+ view.setModel(&model);
+ view.setViewMode(QListView::ListMode);
+ view.setFlow(QListView::TopToBottom);
+
+ QSize sz = view.sizeHintForIndex(model.index(0,0));
+ QModelIndex index;
+ index = view.indexAt(QPoint(20,0));
+ QVERIFY(index.isValid());
+ QCOMPARE(index.row(), 0);
+
+ index = view.indexAt(QPoint(20,sz.height()));
+ QVERIFY(index.isValid());
+ QCOMPARE(index.row(), 1);
+
+ index = view.indexAt(QPoint(20,2 * sz.height()));
+ QVERIFY(!index.isValid());
+
+
+
+ model.rCount = 30;
+ QListViewShowEventListener view2;
+ // Set the height to a small enough value so that it wraps to a new section.
+ view2.resize(300,100);
+ view2.setModel(&model);
+ view2.setFlow(QListView::TopToBottom);
+ view2.setViewMode(QListView::ListMode);
+ view2.setWrapping(true);
+ // We really want to make sure it is shown, because the layout won't be known until it is shown
+ view2.show();
+ for (int i = 0; i < 5 && !view2.m_shown; ++i) {
+ QTest::qWait(500);
+ }
+
+ QVERIFY(view2.m_index.isValid());
+ QVERIFY(view2.m_index.row() != 0);
+
+}
+
+void tst_QListView::clicked()
+{
+ QtTestModel model;
+ model.rCount = 10;
+ model.colCount = 2;
+
+ qRegisterMetaType<QModelIndex>("QModelIndex");
+
+ QListView view;
+ view.setModel(&model);
+
+ view.show();
+ QApplication::processEvents();
+
+ QModelIndex firstIndex = model.index(0, 0, QModelIndex());
+ QVERIFY(firstIndex.isValid());
+ int itemHeight = view.visualRect(firstIndex).height();
+ view.resize(200, itemHeight * (model.rCount + 1));
+
+ for (int i = 0; i < model.rCount; ++i) {
+ QPoint p(5, 1 + itemHeight * i);
+ QModelIndex index = view.indexAt(p);
+ if (!index.isValid())
+ continue;
+ QSignalSpy spy(&view, SIGNAL(clicked(const QModelIndex&)));
+ QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ QCOMPARE(spy.count(), 1);
+ }
+}
+
+void tst_QListView::singleSelectionRemoveRow()
+{
+ QStringList items;
+ items << "item1" << "item2" << "item3" << "item4";
+ QStringListModel model(items);
+
+ QListView view;
+ view.setModel(&model);
+ view.show();
+
+ QModelIndex index;
+ view.setCurrentIndex(model.index(1));
+ index = view.currentIndex();
+ QCOMPARE(view.model()->data(index).toString(), QString("item2"));
+
+ model.removeRow(1);
+ index = view.currentIndex();
+ QCOMPARE(view.model()->data(index).toString(), QString("item3"));
+
+ model.removeRow(0);
+ index = view.currentIndex();
+ QCOMPARE(view.model()->data(index).toString(), QString("item3"));
+}
+
+void tst_QListView::singleSelectionRemoveColumn()
+{
+ int numCols = 3;
+ int numRows = 3;
+ QStandardItemModel model(numCols, numRows);
+ for (int r = 0; r < numRows; ++r)
+ for (int c = 0; c < numCols; ++c)
+ model.setData(model.index(r, c), QString("%1,%2").arg(r).arg(c));
+
+ QListView view;
+ view.setModel(&model);
+ view.show();
+
+ QModelIndex index;
+ view.setCurrentIndex(model.index(1, 1));
+ index = view.currentIndex();
+ QCOMPARE(view.model()->data(index).toString(), QString("1,1"));
+
+ model.removeColumn(1);
+ index = view.currentIndex();
+ QCOMPARE(view.model()->data(index).toString(), QString("1,0"));
+
+ model.removeColumn(0);
+ index = view.currentIndex();
+ QCOMPARE(view.model()->data(index).toString(), QString("1,2"));
+}
+
+void tst_QListView::modelColumn()
+{
+ int numCols = 3;
+ int numRows = 3;
+ QStandardItemModel model(numCols, numRows);
+ for (int r = 0; r < numRows; ++r)
+ for (int c = 0; c < numCols; ++c)
+ model.setData(model.index(r, c), QString("%1,%2").arg(r).arg(c));
+
+
+ QListView view;
+ view.setModel(&model);
+
+
+
+ //
+ // Set and get with a valid model
+ //
+
+ // Default is column 0
+ QCOMPARE(view.modelColumn(), 0);
+
+ view.setModelColumn(0);
+ QCOMPARE(view.modelColumn(), 0);
+ view.setModelColumn(1);
+ QCOMPARE(view.modelColumn(), 1);
+ view.setModelColumn(2);
+ QCOMPARE(view.modelColumn(), 2);
+
+ // Out of bound cases should not modify the modelColumn
+ view.setModelColumn(-1);
+ QCOMPARE(view.modelColumn(), 2);
+ view.setModelColumn(INT_MAX);
+ QCOMPARE(view.modelColumn(), 2);
+
+
+ // See if it displays the right column using indexAt()...
+ view.resize(400,400);
+ view.show();
+
+ for (int c = 0; c < 3; ++c) {
+ view.setModelColumn(c);
+ int startrow = 0;
+ for (int y = 0; y < view.height(); ++y) {
+ QModelIndex idx = view.indexAt( QPoint(1, y) );
+ if (idx.row() == startrow + 1) ++startrow;
+ else if (idx.row() == -1) break;
+ QCOMPARE(idx.row(), startrow);
+ QCOMPARE(idx.column(), c);
+ }
+ QCOMPARE(startrow, 2);
+ }
+}
+
+
+void tst_QListView::hideFirstRow()
+{
+ QStringList items;
+ for (int i=0; i <100; ++i)
+ items << "item";
+ QStringListModel model(items);
+
+ QListView view;
+ view.setModel(&model);
+ view.setUniformItemSizes(true);
+ view.setRowHidden(0,true);
+ view.show();
+ QTest::qWait(100);
+}
+
+void tst_QListView::batchedMode()
+{
+ QStringList items;
+ for (int i=0; i <3; ++i)
+ items << "item";
+ QStringListModel model(items);
+
+ QListView view;
+ view.setModel(&model);
+ view.setUniformItemSizes(true);
+ view.setViewMode(QListView::ListMode);
+ view.setLayoutMode(QListView::Batched);
+ view.setBatchSize(2);
+ view.resize(200,400);
+ view.show();
+
+#if !defined(Q_OS_WINCE)
+ QTest::qWait(100);
+#else
+ QTest::qWait(2000);
+#endif
+ QBitArray ba;
+ for (int y = 0; y < view.height(); ++y) {
+ QModelIndex idx = view.indexAt( QPoint(1, y) );
+ if (!idx.isValid())
+ break;
+ if (idx.row() >= ba.size())
+ ba.resize(idx.row() + 1);
+ ba.setBit(idx.row(), true);
+ }
+ QCOMPARE(ba.size(), 3);
+
+
+ // Test the dynamic listview too.
+ view.setViewMode(QListView::IconMode);
+ view.setLayoutMode(QListView::Batched);
+ view.setFlow(QListView::TopToBottom);
+ view.setBatchSize(2);
+
+#if !defined(Q_OS_WINCE)
+ QTest::qWait(100);
+#else
+ QTest::qWait(2000);
+#endif
+
+ ba.clear();
+ for (int y = 0; y < view.height(); ++y) {
+ QModelIndex idx = view.indexAt( QPoint(1, y) );
+ if (!idx.isValid())
+ break;
+ if (idx.row() >= ba.size())
+ ba.resize(idx.row() + 1);
+ ba.setBit(idx.row(), true);
+ }
+ QCOMPARE(ba.size(), 3);
+
+}
+
+void tst_QListView::setCurrentIndex()
+{
+ QStringList items;
+ int i;
+ for (i=0; i <20; ++i)
+ items << QString("item %1").arg(i);
+ QStringListModel model(items);
+
+ QListView view;
+ view.setModel(&model);
+
+ view.resize(220,182);
+ view.show();
+
+ for (int pass = 0; pass < 2; ++pass) {
+ view.setFlow(pass == 0 ? QListView::TopToBottom : QListView::LeftToRight);
+ QScrollBar *sb = pass == 0 ? view.verticalScrollBar() : view.horizontalScrollBar();
+ QList<QSize> gridsizes;
+ gridsizes << QSize() << QSize(200,38);
+ for (int ig = 0; ig < gridsizes.count(); ++ig) {
+ if (pass == 1 && !gridsizes.at(ig).isValid()) // the width of an item varies, so it might jump two times
+ continue;
+ view.setGridSize(gridsizes.at(ig));
+
+ qApp->processEvents();
+ int offset = sb->value();
+
+ // first "scroll" down, verify that we scroll one step at a time
+ i = 0;
+ for (i = 0; i < 20; ++i) {
+ QModelIndex idx = model.index(i,0);
+ view.setCurrentIndex(idx);
+ if (offset != sb->value()) {
+ // If it has scrolled, it should have scrolled only by one.
+ QCOMPARE(sb->value(), offset + 1);
+ ++offset;
+ }
+ //QTest::qWait(50);
+ }
+
+ --i; // item 20 does not exist
+ // and then "scroll" up, verify that we scroll one step at a time
+ for (; i >= 0; --i) {
+ QModelIndex idx = model.index(i,0);
+ view.setCurrentIndex(idx);
+ if (offset != sb->value()) {
+ // If it has scrolled, it should have scrolled only by one.
+ QCOMPARE(sb->value(), offset - 1);
+ --offset;
+ }
+ //QTest::qWait(50);
+ }
+ }
+ }
+}
+
+class PublicListView : public QListView
+{
+ public:
+ PublicListView(QWidget *parent = 0) : QListView(parent)
+ {
+
+ }
+ void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) {
+ QListView::setSelection(rect, flags);
+ }
+ QSize contentsSize() const { return QListView::contentsSize(); }
+
+ void setPositionForIndex(const QPoint &pos, const QModelIndex &index) {
+ QListView::setPositionForIndex(pos, index);
+ }
+};
+
+class TestDelegate : public QItemDelegate
+{
+public:
+ TestDelegate(QObject *parent) : QItemDelegate(parent), m_sizeHint(50,50) {}
+ QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return m_sizeHint; }
+
+ QSize m_sizeHint;
+};
+
+typedef QList<int> IntList;
+Q_DECLARE_METATYPE(IntList)
+
+void tst_QListView::selection_data()
+{
+ QTest::addColumn<int>("itemCount");
+ QTest::addColumn<int>("viewMode");
+ QTest::addColumn<int>("flow");
+ QTest::addColumn<bool>("wrapping");
+ QTest::addColumn<int>("spacing");
+ QTest::addColumn<QSize>("gridSize");
+ QTest::addColumn<IntList>("hiddenRows");
+ QTest::addColumn<QRect>("selectionRect");
+ QTest::addColumn<IntList>("expectedItems");
+
+ QTest::newRow("select all")
+ << 4 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << false // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(0, 0, 10, 200) // selection rectangle
+ << (IntList() << 0 << 1 << 2 << 3); // expected items
+
+ QTest::newRow("select below, (on viewport)")
+ << 4 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << false // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(10, 250, 1, 1) // selection rectangle
+ << IntList(); // expected items
+
+ QTest::newRow("select below 2, (on viewport)")
+ << 4 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(10, 250, 1, 1) // selection rectangle
+ << IntList(); // expected items
+
+ QTest::newRow("select to the right, (on viewport)")
+ << 40 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(300, 10, 1, 1) // selection rectangle
+ << IntList(); // expected items
+
+ QTest::newRow("select to the right, (on viewport)")
+ << 40 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(300, 0, 1, 300) // selection rectangle
+ << IntList(); // expected items
+
+#if defined(Q_OS_WINCE)
+ // depending on wether the display is double-pixeld, we need
+ // to click at a different position
+ bool doubledSize = false;
+ int dpi = GetDeviceCaps(GetDC(0), LOGPIXELSX);
+ if ((dpi < 1000) && (dpi > 0)) {
+ doubledSize = true;
+ }
+ QTest::newRow("select inside contents, (on viewport)")
+ << 35 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(doubledSize?350:175,doubledSize?550:275, 1, 1)// selection rectangle
+ << IntList(); // expected items
+#else
+ QTest::newRow("select inside contents, (on viewport)")
+ << 35 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(175, 275, 1, 1) // selection rectangle
+ << IntList(); // expected items
+#endif
+
+ QTest::newRow("select a tall rect in LeftToRight flow, wrap items")
+ << 70 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::LeftToRight)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(90, 90, 1, 100) // selection rectangle
+ << (IntList() // expected items
+ << 11 << 12 << 13 << 14 << 15 << 16 << 17 << 18 << 19
+ << 20 << 21 << 22 << 23 << 24 << 25 << 26 << 27 << 28 << 29
+ << 30 << 31);
+
+ QTest::newRow("select a wide rect in LeftToRight, wrap items")
+ << 70 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::LeftToRight)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(90, 90, 200, 1) // selection rectangle
+ << (IntList() // expected items
+ << 11 << 12 << 13 << 14 << 15);
+
+ QTest::newRow("select a wide negative rect in LeftToRight flow, wrap items")
+ << 70 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::LeftToRight)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(290, 90, -200, 1) // selection rectangle
+ << (IntList() // expected items
+ << 11 << 12 << 13 << 14 << 15);
+
+ QTest::newRow("select a tall rect in TopToBottom flow, wrap items")
+ << 70 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(90, 90, 1, 100) // selection rectangle
+ << (IntList() // expected items
+ << 11
+ << 12
+ << 13);
+
+ QTest::newRow("select a tall negative rect in TopToBottom flow, wrap items")
+ << 70 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(90, 190, 1, -100) // selection rectangle
+ << (IntList() // expected items
+ << 11
+ << 12
+ << 13);
+
+ QTest::newRow("select a wide rect in TopToBottom, wrap items")
+ << 70 // itemCount
+ << int(QListView::ListMode)
+ << int(QListView::TopToBottom)
+ << true // wrapping
+ << 0 // spacing
+ << QSize() // gridSize
+ << IntList() // hiddenRows
+ << QRect(90, 90, 100, 1) // selection rectangle
+ << (IntList() // expected items
+ << 20 << 30
+ << 11 << 21 << 31
+ << 12 << 22
+ << 13 << 23
+ << 14 << 24
+ << 15 << 25
+ << 16 << 26
+ << 17 << 27
+ << 18 << 28
+ << 19 << 29);
+}
+
+void tst_QListView::selection()
+{
+ QFETCH(int, itemCount);
+ QFETCH(int, viewMode);
+ QFETCH(int, flow);
+ QFETCH(bool, wrapping);
+ QFETCH(int, spacing);
+ QFETCH(QSize, gridSize);
+ QFETCH(IntList, hiddenRows);
+ QFETCH(QRect, selectionRect);
+ QFETCH(IntList, expectedItems);
+
+ PublicListView v;
+ QtTestModel model;
+ model.colCount = 1;
+ model.rCount = itemCount;
+
+ // avoid scrollbar size mismatches among different styles
+ v.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ v.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ v.setItemDelegate(new TestDelegate(&v));
+ v.setModel(&model);
+ v.setViewMode(QListView::ViewMode(viewMode));
+ v.setFlow(QListView::Flow(flow));
+ v.setWrapping(wrapping);
+ v.setResizeMode(QListView::Adjust);
+ v.setSpacing(spacing);
+ if (gridSize.isValid())
+ v.setGridSize(gridSize);
+ for (int j = 0; j < hiddenRows.count(); ++j) {
+ v.setRowHidden(hiddenRows.at(j), true);
+ }
+
+#if defined(Q_OS_WINCE)
+ // If the device is double-pixeled then the scrollbars become
+ // 10 pixels wider than normal (Windows Style: 16, Windows Mobile Style: 26).
+ // So we have to make the window slightly bigger to have the same count of
+ // items in each row of the list view like in the other styles.
+ static const int dpi = ::GetDeviceCaps(GetDC(0), LOGPIXELSX);
+ if ((dpi < 1000) && (dpi > 0))
+ v.resize(535,535);
+#else
+ v.resize(525,525);
+#endif
+
+ v.show();
+ QApplication::processEvents();
+
+ v.setSelection(selectionRect, QItemSelectionModel::ClearAndSelect);
+
+ QModelIndexList selected = v.selectionModel()->selectedIndexes();
+
+ QCOMPARE(selected.count(), expectedItems.count());
+ for (int i = 0; i < selected.count(); ++i) {
+ QVERIFY(expectedItems.contains(selected.at(i).row()));
+ }
+
+}
+
+void tst_QListView::scrollTo()
+{
+ QListView lv;
+ QStringListModel model(&lv);
+ QStringList list;
+ list << "Short item 1";
+ list << "Short item 2";
+ list << "Short item 3";
+ list << "Short item 4";
+ list << "Short item 5";
+ list << "Short item 6";
+ list << "Begin This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\n"
+ "This is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item\nThis is a very long item End\n";
+ list << "Short item";
+ list << "Short item";
+ list << "Short item";
+ list << "Short item";
+ list << "Short item";
+ list << "Short item";
+ list << "Short item";
+ list << "Short item";
+ model.setStringList(list);
+ lv.setModel(&model);
+ lv.setFixedSize(100, 200);
+ lv.show();
+
+ //by default, the list view scrolls per item and has no wrapping
+ QModelIndex index = model.index(6,0);
+
+ //we save the size of the item for later comparisons
+ const QSize itemsize = lv.visualRect(index).size();
+ QVERIFY(itemsize.height() > lv.height());
+ QVERIFY(itemsize.width() > lv.width());
+
+ //we click the item
+ QPoint p = lv.visualRect(index).center();
+ QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ //let's wait 1 second because the scrolling is delayed
+ QTest::qWait(1000);
+ QCOMPARE(lv.visualRect(index).y(),0);
+
+ //we scroll down. As the item is to tall for the view, it will disappear
+ QTest::keyClick(lv.viewport(), Qt::Key_Down, Qt::NoModifier);
+ QCOMPARE(lv.visualRect(index).y(), -itemsize.height());
+
+ QTest::keyClick(lv.viewport(), Qt::Key_Up, Qt::NoModifier);
+ QCOMPARE(lv.visualRect(index).y(), 0);
+
+ //Let's enable wrapping
+
+ lv.setWrapping(true);
+ lv.horizontalScrollBar()->setValue(0); //let's scroll to the beginning
+
+ //we click the item
+ p = lv.visualRect(index).center();
+ QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ //let's wait 1 second because the scrolling is delayed
+ QTest::qWait(1000);
+ QCOMPARE(lv.visualRect(index).x(),0);
+
+ //we scroll right. As the item is too wide for the view, it will disappear
+ QTest::keyClick(lv.viewport(), Qt::Key_Right, Qt::NoModifier);
+ QCOMPARE(lv.visualRect(index).x(), -itemsize.width());
+
+ QTest::keyClick(lv.viewport(), Qt::Key_Left, Qt::NoModifier);
+ QCOMPARE(lv.visualRect(index).x(), 0);
+
+ lv.setWrapping(false);
+ qApp->processEvents(); //let the layout happen
+
+ //Let's try with scrolling per pixel
+ lv.setHorizontalScrollMode( QListView::ScrollPerPixel);
+ lv.verticalScrollBar()->setValue(0); //scrolls back to the first item
+
+ //we click the item
+ p = lv.visualRect(index).center();
+ QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p);
+ //let's wait 1 second because the scrolling is delayed
+ QTest::qWait(1000);
+ QCOMPARE(lv.visualRect(index).y(),0);
+
+ //we scroll down. As the item is too tall for the view, it will partially disappear
+ QTest::keyClick(lv.viewport(), Qt::Key_Down, Qt::NoModifier);
+ QVERIFY(lv.visualRect(index).y()<0);
+
+ QTest::keyClick(lv.viewport(), Qt::Key_Up, Qt::NoModifier);
+ QCOMPARE(lv.visualRect(index).y(), 0);
+
+}
+
+
+void tst_QListView::scrollBarRanges()
+{
+ const int rowCount = 10;
+ const int rowHeight = 20;
+
+ QListView lv;
+ QStringListModel model(&lv);
+ QStringList list;
+ for (int i = 0; i < rowCount; ++i)
+ list << QString::fromAscii("Item %1").arg(i);
+
+ model.setStringList(list);
+ lv.setModel(&model);
+ lv.resize(250, 130);
+ TestDelegate *delegate = new TestDelegate(&lv);
+ delegate->m_sizeHint = QSize(100, rowHeight);
+ lv.setItemDelegate(delegate);
+ lv.show();
+
+ for (int h = 30; h <= 210; ++h) {
+ lv.resize(250, h);
+ QTest::qWait(100); // wait for the layout to be done
+ int visibleRowCount = lv.viewport()->size().height() / rowHeight;
+ int invisibleRowCount = rowCount - visibleRowCount;
+ QCOMPARE(lv.verticalScrollBar()->maximum(), invisibleRowCount);
+ }
+}
+
+void tst_QListView::scrollBarAsNeeded_data()
+{
+ QTest::addColumn<QSize>("size");
+ QTest::addColumn<int>("itemCount");
+ QTest::addColumn<int>("flow");
+ QTest::addColumn<bool>("horizontalScrollBarVisible");
+ QTest::addColumn<bool>("verticalScrollBarVisible");
+
+
+ QTest::newRow("TopToBottom, count:0")
+ << QSize(200, 100)
+ << 0
+ << int(QListView::TopToBottom)
+ << false
+ << false;
+
+ QTest::newRow("TopToBottom, count:1")
+ << QSize(200, 100)
+ << 1
+ << int(QListView::TopToBottom)
+ << false
+ << false;
+
+ QTest::newRow("TopToBottom, count:20")
+ << QSize(200, 100)
+ << 20
+ << int(QListView::TopToBottom)
+ << false
+ << true;
+
+ QTest::newRow("LeftToRight, count:0")
+ << QSize(200, 100)
+ << 0
+ << int(QListView::LeftToRight)
+ << false
+ << false;
+
+ QTest::newRow("LeftToRight, count:1")
+ << QSize(200, 100)
+ << 1
+ << int(QListView::LeftToRight)
+ << false
+ << false;
+
+ QTest::newRow("LeftToRight, count:20")
+ << QSize(200, 100)
+ << 20
+ << int(QListView::LeftToRight)
+ << true
+ << false;
+
+
+}
+void tst_QListView::scrollBarAsNeeded()
+{
+
+ QFETCH(QSize, size);
+ QFETCH(int, itemCount);
+ QFETCH(int, flow);
+ QFETCH(bool, horizontalScrollBarVisible);
+ QFETCH(bool, verticalScrollBarVisible);
+
+
+ const int rowCounts[3] = {0, 1, 20};
+
+ QListView lv;
+ lv.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ lv.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ lv.setFlow((QListView::Flow)flow);
+ QStringListModel model(&lv);
+ lv.setModel(&model);
+ lv.resize(size);
+ lv.show();
+
+ for (uint r = 0; r < sizeof(rowCounts)/sizeof(int); ++r) {
+ QStringList list;
+ int i;
+ for (i = 0; i < rowCounts[r]; ++i)
+ list << QString::fromAscii("Item %1").arg(i);
+
+ model.setStringList(list);
+ QApplication::processEvents();
+ QTest::qWait(100);
+
+ QStringList replacement;
+ for (i = 0; i < itemCount; ++i) {
+ replacement << QString::fromAscii("Item %1").arg(i);
+ }
+ model.setStringList(replacement);
+
+ QApplication::processEvents();
+ QTest::qWait(100);
+
+ QCOMPARE(lv.horizontalScrollBar()->isVisible(), horizontalScrollBarVisible);
+ QCOMPARE(lv.verticalScrollBar()->isVisible(), verticalScrollBarVisible);
+ }
+}
+
+void tst_QListView::moveItems()
+{
+ QStandardItemModel model;
+ for (int r = 0; r < 4; ++r) {
+ for (int c = 0; c < 4; ++c) {
+ QStandardItem* item = new QStandardItem(QString("standard item (%1,%2)").arg(r).arg(c));
+ model.setItem(r, c, item);
+ }
+ }
+
+ PublicListView view;
+ view.setViewMode(QListView::IconMode);
+ view.setResizeMode(QListView::Fixed);
+ view.setWordWrap(true);
+ view.setModel(&model);
+ view.setItemDelegate(new TestDelegate(&view));
+
+ for (int r = 0; r < model.rowCount(); ++r) {
+ for (int c = 0; c < model.columnCount(); ++c) {
+ const QModelIndex& idx = model.index(r, c);
+ view.setPositionForIndex(QPoint(r * 75, r * 75), idx);
+ }
+ }
+
+ QCOMPARE(view.contentsSize(), QSize(275, 275));
+}
+
+void tst_QListView::wordWrap()
+{
+ QListView lv;
+ lv.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ lv.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ QStringListModel model(&lv);
+ QStringList list;
+ list << "Short item 1";
+ list << "Short item 2";
+ list << "Short item 3";
+ list << "Begin\nThis item take severals Lines\nEnd";
+ list << "And this is a very long item very long item this is a very vary vary long item"
+ "very long very very long long long this is a long item a very long item a very very long item";
+ list << "And this is a second even a little more long very long item very long item this is a very vary vary long item"
+ "very long very very long long long this is a long item a very long item a very very long item";
+ list << "Short item";
+ list << "rzeofig zerig fslfgj smdlfkgj qmsdlfj amrzriougf qsla zrg fgsdf gsdfg sdfgs dfg sdfgcvb sdfg qsdjfh qsdfjklh qs";
+ list << "Short item";
+ model.setStringList(list);
+ lv.setModel(&model);
+ lv.setWordWrap(true);
+ lv.setFixedSize(150, 150);
+ lv.show();
+ QApplication::processEvents();
+ QTest::qWait(100);
+
+ QCOMPARE(lv.horizontalScrollBar()->isVisible(), false);
+ QCOMPARE(lv.verticalScrollBar()->isVisible(), true);
+}
+
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+class SetCurrentIndexAfterAppendRowCrashDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ SetCurrentIndexAfterAppendRowCrashDialog()
+ {
+#if WINVER >= 0x0500
+ listView = new QListView();
+ listView->setViewMode(QListView::IconMode);
+
+ model = new QStandardItemModel(this);
+ listView->setModel(model);
+
+ timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(buttonClicked()));
+ timer->start(1000);
+
+ DWORD lParam = 0xFFFFFFFC/*OBJID_CLIENT*/;
+ DWORD wParam = 0;
+ SendMessage(winId(), WM_GETOBJECT, wParam, lParam);
+#endif
+ }
+
+private slots:
+ void buttonClicked()
+ {
+ timer->stop();
+ QStandardItem *item = new QStandardItem("test");
+ model->appendRow(item);
+ listView->setCurrentIndex(model->indexFromItem(item));
+ close();
+ }
+private:
+ QListView *listView;
+ QStandardItemModel *model;
+ QTimer *timer;
+};
+#endif
+
+void tst_QListView::setCurrentIndexAfterAppendRowCrash()
+{
+#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && WINVER >= 0x0500
+ SetCurrentIndexAfterAppendRowCrashDialog w;
+ w.exec();
+#else
+ QSKIP("This test only makes sense on windows 2000 and higher.", SkipAll);
+#endif
+}
+
+void tst_QListView::emptyItemSize()
+{
+ QStandardItemModel model;
+ for (int r = 0; r < 4; ++r) {
+ QStandardItem* item = new QStandardItem(QString("standard item (%1)").arg(r));
+ model.setItem(r, 0, item);
+ }
+ model.setItem(4, 0, new QStandardItem());
+
+ PublicListView view;
+ view.setModel(&model);
+
+ for (int i = 0; i < 5; ++i)
+ QVERIFY(!view.visualRect(model.index(i, 0)).isEmpty());
+}
+
+void tst_QListView::task203585_selectAll()
+{
+ //we make sure that "select all" doesn't select the hidden items
+ QListView view;
+ view.setSelectionMode(QAbstractItemView::ExtendedSelection);
+ view.setModel(new QStringListModel( QStringList() << "foo"));
+ view.setRowHidden(0, true);
+ view.selectAll();
+ QVERIFY(view.selectionModel()->selectedIndexes().isEmpty());
+ view.setRowHidden(0, false);
+ view.selectAll();
+ QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
+}
+
+void tst_QListView::task228566_infiniteRelayout()
+{
+ QListView view;
+
+ QStringList list;
+ for (int i = 0; i < 10; ++i) {
+ list << "small";
+ }
+
+ list << "BIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIG";
+ list << "BIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIG";
+
+ QStringListModel model(list);
+ view.setModel(&model);
+ view.setWrapping(true);
+ view.setResizeMode(QListView::Adjust);
+
+ const int itemHeight = view.visualRect( model.index(0, 0)).height();
+
+ view.setFixedHeight(itemHeight * 12);
+ view.show();
+ QTest::qWait(100); //make sure the layout is done once
+
+ QSignalSpy spy(view.horizontalScrollBar(), SIGNAL(rangeChanged(int, int)));
+
+ QTest::qWait(200);
+ //the layout should already have been done
+ //so there should be no change made to the scrollbar
+ QCOMPARE(spy.count(), 0);
+}
+
+
+QTEST_MAIN(tst_QListView)
+#include "tst_qlistview.moc"