tests/auto/qlistview/tst_qlistview.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the test suite of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 
       
    43 #include <QtTest/QtTest>
       
    44 
       
    45 #include <qabstractitemmodel.h>
       
    46 #include <qapplication.h>
       
    47 #include <qlistview.h>
       
    48 #include <qitemdelegate.h>
       
    49 #include <qstandarditemmodel.h>
       
    50 #include <qstringlistmodel.h>
       
    51 #ifndef Q_OS_SYMBIAN
       
    52 #include <cmath>
       
    53 #endif
       
    54 #include <math.h>
       
    55 #include <QtGui/QScrollBar>
       
    56 #include <QtGui/QDialog>
       
    57 #include <QtGui/QStyledItemDelegate>
       
    58 #if defined(Q_OS_WIN) || defined(Q_OS_WINCE)
       
    59 #include <windows.h>
       
    60 #endif
       
    61 
       
    62 #include "../../shared/util.h"
       
    63 
       
    64 //TESTED_CLASS=
       
    65 //TESTED_FILES=
       
    66 
       
    67 class tst_QListView : public QObject
       
    68 {
       
    69     Q_OBJECT
       
    70 
       
    71 public:
       
    72     tst_QListView();
       
    73     virtual ~tst_QListView();
       
    74 
       
    75 
       
    76 public slots:
       
    77     void initTestCase();
       
    78     void cleanupTestCase();
       
    79     void init();
       
    80     void cleanup();
       
    81 private slots:
       
    82     void getSetCheck();
       
    83     void noDelegate();
       
    84     void noModel();
       
    85     void emptyModel();
       
    86     void removeRows();
       
    87     void cursorMove();
       
    88     void hideRows();
       
    89     void moveCursor();
       
    90     void moveCursor2();
       
    91     void moveCursor3();
       
    92     void indexAt();
       
    93     void clicked();
       
    94     void singleSelectionRemoveRow();
       
    95     void singleSelectionRemoveColumn();
       
    96     void modelColumn();
       
    97     void hideFirstRow();
       
    98     void batchedMode();
       
    99     void setCurrentIndex();
       
   100     void selection_data();
       
   101     void selection();
       
   102     void scrollTo();
       
   103     void scrollBarRanges();
       
   104     void scrollBarAsNeeded_data();
       
   105     void scrollBarAsNeeded();
       
   106     void moveItems();
       
   107     void wordWrap();
       
   108     void setCurrentIndexAfterAppendRowCrash();
       
   109     void emptyItemSize();
       
   110     void task203585_selectAll();
       
   111     void task228566_infiniteRelayout();
       
   112     void task248430_crashWith0SizedItem();
       
   113     void task250446_scrollChanged();
       
   114     void task196118_visualRegionForSelection();
       
   115     void task254449_draggingItemToNegativeCoordinates();
       
   116     void keyboardSearch();
       
   117     void shiftSelectionWithNonUniformItemSizes();
       
   118     void clickOnViewportClearsSelection();
       
   119     void task262152_setModelColumnNavigate();
       
   120     void taskQTBUG_2233_scrollHiddenItems_data();
       
   121     void taskQTBUG_2233_scrollHiddenItems();
       
   122 };
       
   123 
       
   124 // Testing get/set functions
       
   125 void tst_QListView::getSetCheck()
       
   126 {
       
   127     QListView obj1;
       
   128     // Movement QListView::movement()
       
   129     // void QListView::setMovement(Movement)
       
   130     obj1.setMovement(QListView::Movement(QListView::Static));
       
   131     QCOMPARE(QListView::Movement(QListView::Static), obj1.movement());
       
   132     obj1.setMovement(QListView::Movement(QListView::Free));
       
   133     QCOMPARE(QListView::Movement(QListView::Free), obj1.movement());
       
   134     obj1.setMovement(QListView::Movement(QListView::Snap));
       
   135     QCOMPARE(QListView::Movement(QListView::Snap), obj1.movement());
       
   136 
       
   137     // Flow QListView::flow()
       
   138     // void QListView::setFlow(Flow)
       
   139     obj1.setFlow(QListView::Flow(QListView::LeftToRight));
       
   140     QCOMPARE(QListView::Flow(QListView::LeftToRight), obj1.flow());
       
   141     obj1.setFlow(QListView::Flow(QListView::TopToBottom));
       
   142     QCOMPARE(QListView::Flow(QListView::TopToBottom), obj1.flow());
       
   143 
       
   144     // ResizeMode QListView::resizeMode()
       
   145     // void QListView::setResizeMode(ResizeMode)
       
   146     obj1.setResizeMode(QListView::ResizeMode(QListView::Fixed));
       
   147     QCOMPARE(QListView::ResizeMode(QListView::Fixed), obj1.resizeMode());
       
   148     obj1.setResizeMode(QListView::ResizeMode(QListView::Adjust));
       
   149     QCOMPARE(QListView::ResizeMode(QListView::Adjust), obj1.resizeMode());
       
   150 
       
   151     // LayoutMode QListView::layoutMode()
       
   152     // void QListView::setLayoutMode(LayoutMode)
       
   153     obj1.setLayoutMode(QListView::LayoutMode(QListView::SinglePass));
       
   154     QCOMPARE(QListView::LayoutMode(QListView::SinglePass), obj1.layoutMode());
       
   155     obj1.setLayoutMode(QListView::LayoutMode(QListView::Batched));
       
   156     QCOMPARE(QListView::LayoutMode(QListView::Batched), obj1.layoutMode());
       
   157 
       
   158     // int QListView::spacing()
       
   159     // void QListView::setSpacing(int)
       
   160     obj1.setSpacing(0);
       
   161     QCOMPARE(0, obj1.spacing());
       
   162     obj1.setSpacing(INT_MIN);
       
   163     QCOMPARE(INT_MIN, obj1.spacing());
       
   164     obj1.setSpacing(INT_MAX);
       
   165     QCOMPARE(INT_MAX, obj1.spacing());
       
   166 
       
   167     // ViewMode QListView::viewMode()
       
   168     // void QListView::setViewMode(ViewMode)
       
   169     obj1.setViewMode(QListView::ViewMode(QListView::ListMode));
       
   170     QCOMPARE(QListView::ViewMode(QListView::ListMode), obj1.viewMode());
       
   171     obj1.setViewMode(QListView::ViewMode(QListView::IconMode));
       
   172     QCOMPARE(QListView::ViewMode(QListView::IconMode), obj1.viewMode());
       
   173 
       
   174     // int QListView::modelColumn()
       
   175     // void QListView::setModelColumn(int)
       
   176     obj1.setModelColumn(0);
       
   177     QCOMPARE(0, obj1.modelColumn());
       
   178     obj1.setModelColumn(INT_MIN);
       
   179     QCOMPARE(0, obj1.modelColumn()); // Less than 0 => 0
       
   180     obj1.setModelColumn(INT_MAX);
       
   181     QCOMPARE(0, obj1.modelColumn()); // No model => 0
       
   182 
       
   183     // bool QListView::uniformItemSizes()
       
   184     // void QListView::setUniformItemSizes(bool)
       
   185     obj1.setUniformItemSizes(false);
       
   186     QCOMPARE(false, obj1.uniformItemSizes());
       
   187     obj1.setUniformItemSizes(true);
       
   188     QCOMPARE(true, obj1.uniformItemSizes());
       
   189 
       
   190     // make sure setViewMode() doesn't reset resizeMode
       
   191     obj1.clearPropertyFlags();
       
   192     obj1.setResizeMode(QListView::Adjust);
       
   193     obj1.setViewMode(QListView::IconMode);
       
   194     QCOMPARE(obj1.resizeMode(), QListView::Adjust);
       
   195 
       
   196     obj1.setWordWrap(false);
       
   197     QCOMPARE(false, obj1.wordWrap());
       
   198     obj1.setWordWrap(true);
       
   199     QCOMPARE(true, obj1. wordWrap());
       
   200 }
       
   201 
       
   202 class QtTestModel: public QAbstractListModel
       
   203 {
       
   204 public:
       
   205     QtTestModel(QObject *parent = 0): QAbstractListModel(parent),
       
   206        colCount(0), rCount(0), wrongIndex(false) {}
       
   207     int rowCount(const QModelIndex&) const { return rCount; }
       
   208     int columnCount(const QModelIndex&) const { return colCount; }
       
   209     bool isEditable(const QModelIndex &) const { return true; }
       
   210 
       
   211     QVariant data(const QModelIndex &idx, int role) const
       
   212     {
       
   213 
       
   214         if (!m_icon.isNull() && role == Qt::DecorationRole) {
       
   215             return m_icon;
       
   216         }
       
   217         if (role != Qt::DisplayRole)
       
   218             return QVariant();
       
   219 
       
   220         if (idx.row() < 0 || idx.column() < 0 || idx.column() >= colCount
       
   221             || idx.row() >= rCount) {
       
   222             wrongIndex = true;
       
   223             qWarning("got invalid modelIndex %d/%d", idx.row(), idx.column());
       
   224         }
       
   225         return QString("%1/%2").arg(idx.row()).arg(idx.column());
       
   226     }
       
   227 
       
   228     void removeLastRow()
       
   229     {
       
   230         beginRemoveRows(QModelIndex(), rCount - 2, rCount - 1);
       
   231         --rCount;
       
   232         endRemoveRows();
       
   233     }
       
   234 
       
   235     void removeAllRows()
       
   236     {
       
   237         beginRemoveRows(QModelIndex(), 0, rCount - 1);
       
   238         rCount = 0;
       
   239         endRemoveRows();
       
   240     }
       
   241 
       
   242     void setDataIcon(const QIcon &icon)
       
   243     {
       
   244         m_icon = icon;
       
   245     }
       
   246 
       
   247     int colCount, rCount;
       
   248     QIcon m_icon;
       
   249     mutable bool wrongIndex;
       
   250 };
       
   251 
       
   252 tst_QListView::tst_QListView()
       
   253 {
       
   254 }
       
   255 
       
   256 tst_QListView::~tst_QListView()
       
   257 {
       
   258 }
       
   259 
       
   260 void tst_QListView::initTestCase()
       
   261 {
       
   262 }
       
   263 
       
   264 void tst_QListView::cleanupTestCase()
       
   265 {
       
   266 }
       
   267 
       
   268 void tst_QListView::init()
       
   269 {
       
   270 #ifdef Q_OS_WINCE //disable magic for WindowsCE
       
   271     qApp->setAutoMaximizeThreshold(-1);
       
   272 #endif
       
   273 }
       
   274 
       
   275 void tst_QListView::cleanup()
       
   276 {
       
   277 }
       
   278 
       
   279 
       
   280 void tst_QListView::noDelegate()
       
   281 {
       
   282     QtTestModel model(0);
       
   283     model.rCount = model.colCount = 10;
       
   284     QListView view;
       
   285     view.setModel(&model);
       
   286     view.setItemDelegate(0);
       
   287     view.show();
       
   288 }
       
   289 
       
   290 void tst_QListView::noModel()
       
   291 {
       
   292     QListView view;
       
   293     view.show();
       
   294     view.setRowHidden(0, true);
       
   295 }
       
   296 
       
   297 void tst_QListView::emptyModel()
       
   298 {
       
   299     QtTestModel model(0);
       
   300     QListView view;
       
   301     view.setModel(&model);
       
   302     view.show();
       
   303     QVERIFY(!model.wrongIndex);
       
   304 }
       
   305 
       
   306 void tst_QListView::removeRows()
       
   307 {
       
   308     QtTestModel model(0);
       
   309     model.rCount = model.colCount = 10;
       
   310 
       
   311     QListView view;
       
   312     view.setModel(&model);
       
   313     view.show();
       
   314 
       
   315     model.removeLastRow();
       
   316     QVERIFY(!model.wrongIndex);
       
   317 
       
   318     model.removeAllRows();
       
   319     QVERIFY(!model.wrongIndex);
       
   320 }
       
   321 
       
   322 void tst_QListView::cursorMove()
       
   323 {
       
   324     int rows = 6*6;
       
   325     int columns = 6;
       
   326 
       
   327     QStandardItemModel model(rows, columns);
       
   328     QListView view;
       
   329     view.setModel(&model);
       
   330 
       
   331     for (int j = 0; j < columns; ++j) {
       
   332         view.setModelColumn(j);
       
   333         for (int i = 0; i < rows; ++i) {
       
   334             QModelIndex index = model.index(i, j);
       
   335             model.setData(index, QString("[%1,%2]").arg(i).arg(j));
       
   336             view.setCurrentIndex(index);
       
   337             QApplication::processEvents();
       
   338             QCOMPARE(view.currentIndex(), index);
       
   339         }
       
   340     }
       
   341 
       
   342     QSize cellsize(60, 25);
       
   343     int gap = 1; // compensate for the scrollbars
       
   344     int displayColumns = 6;
       
   345 
       
   346     view.resize((displayColumns + gap) * cellsize.width(),
       
   347                  int((ceil(double(rows) / displayColumns) + gap) * cellsize.height()));
       
   348     view.setResizeMode(QListView::Adjust);
       
   349     view.setGridSize(cellsize);
       
   350     view.setViewMode(QListView::IconMode);
       
   351     view.doItemsLayout();
       
   352     view.show();
       
   353 
       
   354     QVector<Qt::Key> keymoves;
       
   355     keymoves << Qt::Key_Up << Qt::Key_Up << Qt::Key_Right << Qt::Key_Right << Qt::Key_Up
       
   356              << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down << Qt::Key_Up
       
   357              << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up
       
   358              << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down;
       
   359 
       
   360     int displayRow    = rows / displayColumns - 1;
       
   361     int displayColumn = displayColumns - (rows % displayColumns) - 1;
       
   362 
       
   363     QApplication::instance()->processEvents();
       
   364     for (int i = 0; i < keymoves.size(); ++i) {
       
   365         Qt::Key key = keymoves.at(i);
       
   366         QTest::keyClick(&view, key);
       
   367         switch (key) {
       
   368         case Qt::Key_Up:
       
   369             displayRow = qMax(0, displayRow - 1);
       
   370             break;
       
   371         case Qt::Key_Down:
       
   372             displayRow = qMin(rows / displayColumns - 1, displayRow + 1);
       
   373             break;
       
   374         case Qt::Key_Left:
       
   375             displayColumn = qMax(0, displayColumn - 1);
       
   376             break;
       
   377         case Qt::Key_Right:
       
   378             displayColumn = qMin(displayColumns-1, displayColumn + 1);
       
   379             break;
       
   380         default:
       
   381             QVERIFY(false);
       
   382         }
       
   383 
       
   384         QApplication::instance()->processEvents();
       
   385 
       
   386         int row = displayRow * displayColumns + displayColumn;
       
   387         int column = columns - 1;
       
   388         QModelIndex index = model.index(row, column);
       
   389         QCOMPARE(view.currentIndex().row(), row);
       
   390         QCOMPARE(view.currentIndex().column(), column);
       
   391         QCOMPARE(view.currentIndex(), index);
       
   392     }
       
   393 }
       
   394 
       
   395 void tst_QListView::hideRows()
       
   396 {
       
   397     QtTestModel model(0);
       
   398     model.rCount = model.colCount = 10;
       
   399 
       
   400     QListView view;
       
   401     view.setModel(&model);
       
   402     view.show();
       
   403 
       
   404     // hide then show
       
   405     QVERIFY(!view.isRowHidden(2));
       
   406     view.setRowHidden(2, true);
       
   407     QVERIFY(view.isRowHidden(2));
       
   408     view.setRowHidden(2, false);
       
   409     QVERIFY(!view.isRowHidden(2));
       
   410 
       
   411     // re show same row
       
   412     QVERIFY(!view.isRowHidden(2));
       
   413     view.setRowHidden(2, false);
       
   414     QVERIFY(!view.isRowHidden(2));
       
   415 
       
   416     // double hidding
       
   417     QVERIFY(!view.isRowHidden(2));
       
   418     view.setRowHidden(2, true);
       
   419     QVERIFY(view.isRowHidden(2));
       
   420     view.setRowHidden(2, true);
       
   421     QVERIFY(view.isRowHidden(2));
       
   422     view.setRowHidden(2, false);
       
   423     QVERIFY(!view.isRowHidden(2));
       
   424 
       
   425     // show in per-item mode, then hide the first row
       
   426     view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem);
       
   427     QVERIFY(!view.isRowHidden(0));
       
   428     view.setRowHidden(0, true);
       
   429     QVERIFY(view.isRowHidden(0));
       
   430     view.setRowHidden(0, false);
       
   431     QVERIFY(!view.isRowHidden(0));
       
   432 
       
   433     QStandardItemModel sim(0);
       
   434     QStandardItem *root = new QStandardItem("Root row");
       
   435     for (int i=0;i<5;i++)
       
   436         root->appendRow(new QStandardItem(QString("Row %1").arg(i)));
       
   437     sim.appendRow(root);
       
   438     view.setModel(&sim);
       
   439     view.setRootIndex(root->index());
       
   440     QVERIFY(!view.isRowHidden(0));
       
   441     view.setRowHidden(0, true);
       
   442     QVERIFY(view.isRowHidden(0));
       
   443     view.setRowHidden(0, false);
       
   444     QVERIFY(!view.isRowHidden(0));
       
   445 }
       
   446 
       
   447 
       
   448 void tst_QListView::moveCursor()
       
   449 {
       
   450     QtTestModel model(0);
       
   451     model.rCount = model.colCount = 10;
       
   452 
       
   453     QListView view;
       
   454     view.setModel(&model);
       
   455 
       
   456     QTest::keyClick(&view, Qt::Key_Down);
       
   457 
       
   458     view.setModel(0);
       
   459     view.setModel(&model);
       
   460     view.setRowHidden(0, true);
       
   461 
       
   462     QTest::keyClick(&view, Qt::Key_Down);
       
   463     QCOMPARE(view.selectionModel()->currentIndex(), model.index(1, 0));
       
   464 }
       
   465 
       
   466 class QMoveCursorListView : public QListView
       
   467 {
       
   468 public:
       
   469     QMoveCursorListView() : QListView() {}
       
   470 
       
   471     enum CursorAction { MoveUp, MoveDown, MoveLeft, MoveRight,
       
   472         MoveHome, MoveEnd, MovePageUp, MovePageDown,
       
   473         MoveNext, MovePrevious };
       
   474 
       
   475     QModelIndex moveCursor(QMoveCursorListView::CursorAction action, Qt::KeyboardModifiers modifiers)
       
   476     {
       
   477         return QListView::moveCursor((QListView::CursorAction)action, modifiers);
       
   478     }
       
   479 };
       
   480 
       
   481 void tst_QListView::moveCursor2()
       
   482 {
       
   483     QtTestModel model(0);
       
   484     model.colCount = 1;
       
   485     model.rCount = 100;
       
   486     QPixmap pm(32, 32);
       
   487     pm.fill(Qt::green);
       
   488     model.setDataIcon(QIcon(pm));
       
   489 
       
   490     QMoveCursorListView vu;
       
   491     vu.setModel(&model);
       
   492     vu.setIconSize(QSize(36,48));
       
   493     vu.setGridSize(QSize(34,56));
       
   494     //Standard framesize is 1. If Framesize > 2 increase size
       
   495     int frameSize = qApp->style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
       
   496     vu.resize(300 + frameSize * 2,300);
       
   497     vu.setFlow(QListView::LeftToRight);
       
   498     vu.setMovement(QListView::Static);
       
   499     vu.setWrapping(true);
       
   500     vu.setViewMode(QListView::IconMode);
       
   501     vu.setLayoutMode(QListView::Batched);
       
   502     vu.show();
       
   503     vu.selectionModel()->setCurrentIndex(model.index(0,0), QItemSelectionModel::SelectCurrent);
       
   504     QCoreApplication::processEvents();
       
   505 
       
   506     QModelIndex idx = vu.moveCursor(QMoveCursorListView::MoveHome, Qt::NoModifier);
       
   507     QCOMPARE(idx, model.index(0,0));
       
   508     idx = vu.moveCursor(QMoveCursorListView::MoveDown, Qt::NoModifier);
       
   509     QModelIndex p = model.index(8,0);
       
   510     QCOMPARE(idx, model.index(8,0));
       
   511 
       
   512 }
       
   513 
       
   514 void tst_QListView::moveCursor3()
       
   515 {
       
   516     //this tests is for task 159792
       
   517     //it tests that navigation works even with non uniform item sizes
       
   518     QListView view;
       
   519     QStandardItemModel model(0, 1);
       
   520     QStandardItem *i1 = new QStandardItem("First item, long name");
       
   521     QStandardItem *i2 = new QStandardItem("2nd item");
       
   522     QStandardItem *i3 = new QStandardItem("Third item, long name");
       
   523     i1->setSizeHint(QSize(200,32));
       
   524     model.appendRow(i1);
       
   525     model.appendRow(i2);
       
   526     model.appendRow(i3);
       
   527     view.setModel(&model);
       
   528 
       
   529     view.setCurrentIndex(model.index(0, 0));
       
   530 
       
   531     QCOMPARE(view.selectionModel()->currentIndex(), model.index(0, 0));
       
   532     QTest::keyClick(&view, Qt::Key_Down);
       
   533     QCOMPARE(view.selectionModel()->currentIndex(), model.index(1, 0));
       
   534     QTest::keyClick(&view, Qt::Key_Down);
       
   535     QCOMPARE(view.selectionModel()->currentIndex(), model.index(2, 0));
       
   536     QTest::keyClick(&view, Qt::Key_Up);
       
   537     QCOMPARE(view.selectionModel()->currentIndex(), model.index(1, 0));
       
   538     QTest::keyClick(&view, Qt::Key_Up);
       
   539     QCOMPARE(view.selectionModel()->currentIndex(), model.index(0, 0));
       
   540 }
       
   541 
       
   542 
       
   543 class QListViewShowEventListener : public QListView
       
   544 {
       
   545 public:
       
   546     QListViewShowEventListener() : QListView() { m_shown = false;}
       
   547 
       
   548     virtual void showEvent(QShowEvent * /*e*/)
       
   549     {
       
   550         int columnwidth = sizeHintForColumn(0);
       
   551         QSize sz = sizeHintForIndex(model()->index(0,0));
       
   552 
       
   553         // This should retrieve a model index in the 2nd section
       
   554         m_index = indexAt(QPoint(columnwidth +2, sz.height()/2));
       
   555         m_shown = true;
       
   556     }
       
   557 
       
   558     QModelIndex m_index;
       
   559     bool m_shown;
       
   560 
       
   561 };
       
   562 
       
   563 void tst_QListView::indexAt()
       
   564 {
       
   565     QtTestModel model(0);
       
   566     model.rCount = 2;
       
   567     model.colCount = 1;
       
   568 
       
   569     QListView view;
       
   570     view.setModel(&model);
       
   571     view.setViewMode(QListView::ListMode);
       
   572     view.setFlow(QListView::TopToBottom);
       
   573 
       
   574     QSize sz = view.sizeHintForIndex(model.index(0,0));
       
   575     QModelIndex index;
       
   576     index = view.indexAt(QPoint(20,0));
       
   577     QVERIFY(index.isValid());
       
   578     QCOMPARE(index.row(), 0);
       
   579 
       
   580     index = view.indexAt(QPoint(20,sz.height()));
       
   581     QVERIFY(index.isValid());
       
   582     QCOMPARE(index.row(), 1);
       
   583 
       
   584     index = view.indexAt(QPoint(20,2 * sz.height()));
       
   585     QVERIFY(!index.isValid());
       
   586 
       
   587 
       
   588 
       
   589     model.rCount = 30;
       
   590     QListViewShowEventListener view2;
       
   591     // Set the height to a small enough value so that it wraps to a new section.
       
   592     view2.resize(300,100);
       
   593     view2.setModel(&model);
       
   594     view2.setFlow(QListView::TopToBottom);
       
   595     view2.setViewMode(QListView::ListMode);
       
   596     view2.setWrapping(true);
       
   597     // We really want to make sure it is shown, because the layout won't be known until it is shown
       
   598     view2.show();
       
   599     for (int i = 0; i < 5 && !view2.m_shown; ++i) {
       
   600         QTest::qWait(500);
       
   601     }
       
   602 
       
   603     QVERIFY(view2.m_index.isValid());
       
   604     QVERIFY(view2.m_index.row() != 0);
       
   605 
       
   606 }
       
   607 
       
   608 void tst_QListView::clicked()
       
   609 {
       
   610     QtTestModel model;
       
   611     model.rCount = 10;
       
   612     model.colCount = 2;
       
   613 
       
   614     qRegisterMetaType<QModelIndex>("QModelIndex");
       
   615 
       
   616     QListView view;
       
   617     view.setModel(&model);
       
   618 
       
   619     view.show();
       
   620     QApplication::processEvents();
       
   621 
       
   622     QModelIndex firstIndex = model.index(0, 0, QModelIndex());
       
   623     QVERIFY(firstIndex.isValid());
       
   624     int itemHeight = view.visualRect(firstIndex).height();
       
   625     view.resize(200, itemHeight * (model.rCount + 1));
       
   626 
       
   627     for (int i = 0; i < model.rCount; ++i) {
       
   628         QPoint p(5, 1 + itemHeight * i);
       
   629         QModelIndex index = view.indexAt(p);
       
   630         if (!index.isValid())
       
   631             continue;
       
   632         QSignalSpy spy(&view, SIGNAL(clicked(const QModelIndex&)));
       
   633         QTest::mouseClick(view.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
   634         QCOMPARE(spy.count(), 1);
       
   635     }
       
   636 }
       
   637 
       
   638 void tst_QListView::singleSelectionRemoveRow()
       
   639 {
       
   640     QStringList items;
       
   641     items << "item1" << "item2" << "item3" << "item4";
       
   642     QStringListModel model(items);
       
   643 
       
   644     QListView view;
       
   645     view.setModel(&model);
       
   646     view.show();
       
   647 
       
   648     QModelIndex index;
       
   649     view.setCurrentIndex(model.index(1));
       
   650     index = view.currentIndex();
       
   651     QCOMPARE(view.model()->data(index).toString(), QString("item2"));
       
   652 
       
   653     model.removeRow(1);
       
   654     index = view.currentIndex();
       
   655     QCOMPARE(view.model()->data(index).toString(), QString("item3"));
       
   656 
       
   657     model.removeRow(0);
       
   658     index = view.currentIndex();
       
   659     QCOMPARE(view.model()->data(index).toString(), QString("item3"));
       
   660 }
       
   661 
       
   662 void tst_QListView::singleSelectionRemoveColumn()
       
   663 {
       
   664     int numCols = 3;
       
   665     int numRows = 3;
       
   666     QStandardItemModel model(numCols, numRows);
       
   667     for (int r = 0; r < numRows; ++r)
       
   668         for (int c = 0; c < numCols; ++c)
       
   669             model.setData(model.index(r, c), QString("%1,%2").arg(r).arg(c));
       
   670 
       
   671     QListView view;
       
   672     view.setModel(&model);
       
   673     view.show();
       
   674 
       
   675     QModelIndex index;
       
   676     view.setCurrentIndex(model.index(1, 1));
       
   677     index = view.currentIndex();
       
   678     QCOMPARE(view.model()->data(index).toString(), QString("1,1"));
       
   679 
       
   680     model.removeColumn(1);
       
   681     index = view.currentIndex();
       
   682     QCOMPARE(view.model()->data(index).toString(), QString("1,0"));
       
   683 
       
   684     model.removeColumn(0);
       
   685     index = view.currentIndex();
       
   686     QCOMPARE(view.model()->data(index).toString(), QString("1,2"));
       
   687 }
       
   688 
       
   689 void tst_QListView::modelColumn()
       
   690 {
       
   691     int numCols = 3;
       
   692     int numRows = 3;
       
   693     QStandardItemModel model(numCols, numRows);
       
   694     for (int r = 0; r < numRows; ++r)
       
   695         for (int c = 0; c < numCols; ++c)
       
   696             model.setData(model.index(r, c), QString("%1,%2").arg(r).arg(c));
       
   697 
       
   698 
       
   699     QListView view;
       
   700     view.setModel(&model);
       
   701 
       
   702 
       
   703 
       
   704     //
       
   705     // Set and get with a valid model
       
   706     //
       
   707 
       
   708     // Default is column 0
       
   709     QCOMPARE(view.modelColumn(), 0);
       
   710 
       
   711     view.setModelColumn(0);
       
   712     QCOMPARE(view.modelColumn(), 0);
       
   713     view.setModelColumn(1);
       
   714     QCOMPARE(view.modelColumn(), 1);
       
   715     view.setModelColumn(2);
       
   716     QCOMPARE(view.modelColumn(), 2);
       
   717 
       
   718     // Out of bound cases should not modify the modelColumn
       
   719     view.setModelColumn(-1);
       
   720     QCOMPARE(view.modelColumn(), 2);
       
   721     view.setModelColumn(INT_MAX);
       
   722     QCOMPARE(view.modelColumn(), 2);
       
   723 
       
   724 
       
   725     // See if it displays the right column using indexAt()...
       
   726     view.resize(400,400);
       
   727     view.show();
       
   728 
       
   729     for (int c = 0; c < 3; ++c) {
       
   730         view.setModelColumn(c);
       
   731         int startrow = 0;
       
   732         for (int y = 0; y < view.height(); ++y) {
       
   733             QModelIndex idx = view.indexAt( QPoint(1, y) );
       
   734             if (idx.row() == startrow + 1) ++startrow;
       
   735             else if (idx.row() == -1) break;
       
   736             QCOMPARE(idx.row(), startrow);
       
   737             QCOMPARE(idx.column(), c);
       
   738         }
       
   739         QCOMPARE(startrow, 2);
       
   740     }
       
   741 }
       
   742 
       
   743 
       
   744 void tst_QListView::hideFirstRow()
       
   745 {
       
   746     QStringList items;
       
   747     for (int i=0; i <100; ++i)
       
   748         items << "item";
       
   749     QStringListModel model(items);
       
   750 
       
   751     QListView view;
       
   752     view.setModel(&model);
       
   753     view.setUniformItemSizes(true);
       
   754     view.setRowHidden(0,true);
       
   755     view.show();
       
   756     QTest::qWait(100);
       
   757 }
       
   758 
       
   759 void tst_QListView::batchedMode()
       
   760 {
       
   761     QStringList items;
       
   762     for (int i=0; i <3; ++i)
       
   763         items << "item";
       
   764     QStringListModel model(items);
       
   765 
       
   766     QListView view;
       
   767     view.setModel(&model);
       
   768     view.setUniformItemSizes(true);
       
   769     view.setViewMode(QListView::ListMode);
       
   770     view.setLayoutMode(QListView::Batched);
       
   771     view.setBatchSize(2);
       
   772     view.resize(200,400);
       
   773     view.show();
       
   774 
       
   775 #if !defined(Q_OS_WINCE)
       
   776     QTest::qWait(100);
       
   777 #else
       
   778     QTest::qWait(2000);
       
   779 #endif
       
   780     QBitArray ba;
       
   781     for (int y = 0; y < view.height(); ++y) {
       
   782         QModelIndex idx = view.indexAt( QPoint(1, y) );
       
   783         if (!idx.isValid())
       
   784             break;
       
   785         if (idx.row() >= ba.size())
       
   786             ba.resize(idx.row() + 1);
       
   787         ba.setBit(idx.row(), true);
       
   788     }
       
   789     QCOMPARE(ba.size(), 3);
       
   790 
       
   791 
       
   792     // Test the dynamic listview too.
       
   793     view.setViewMode(QListView::IconMode);
       
   794     view.setLayoutMode(QListView::Batched);
       
   795     view.setFlow(QListView::TopToBottom);
       
   796     view.setBatchSize(2);
       
   797 
       
   798 #if !defined(Q_OS_WINCE)
       
   799     QTest::qWait(100);
       
   800 #else
       
   801     QTest::qWait(2000);
       
   802 #endif
       
   803 
       
   804     ba.clear();
       
   805     for (int y = 0; y < view.height(); ++y) {
       
   806         QModelIndex idx = view.indexAt( QPoint(1, y) );
       
   807         if (!idx.isValid())
       
   808             break;
       
   809         if (idx.row() >= ba.size())
       
   810             ba.resize(idx.row() + 1);
       
   811         ba.setBit(idx.row(), true);
       
   812     }
       
   813     QCOMPARE(ba.size(), 3);
       
   814 
       
   815 }
       
   816 
       
   817 void tst_QListView::setCurrentIndex()
       
   818 {
       
   819     QStringList items;
       
   820     int i;
       
   821     for (i=0; i <20; ++i)
       
   822         items << QString("item %1").arg(i);
       
   823     QStringListModel model(items);
       
   824 
       
   825     QListView view;
       
   826     view.setModel(&model);
       
   827 
       
   828     view.resize(220,182);
       
   829     view.show();
       
   830 
       
   831     for (int pass = 0; pass < 2; ++pass) {
       
   832         view.setFlow(pass == 0 ? QListView::TopToBottom : QListView::LeftToRight);
       
   833         QScrollBar *sb = pass == 0 ? view.verticalScrollBar() : view.horizontalScrollBar();
       
   834         QList<QSize> gridsizes;
       
   835         gridsizes << QSize() << QSize(200,38);
       
   836         for (int ig = 0; ig < gridsizes.count(); ++ig) {
       
   837             if (pass == 1 && !gridsizes.at(ig).isValid()) // the width of an item varies, so it might jump two times
       
   838                 continue;
       
   839             view.setGridSize(gridsizes.at(ig));
       
   840 
       
   841             qApp->processEvents();
       
   842             int offset = sb->value();
       
   843 
       
   844             // first "scroll" down, verify that we scroll one step at a time
       
   845             i = 0;
       
   846             for (i = 0; i < 20; ++i) {
       
   847                 QModelIndex idx = model.index(i,0);
       
   848                 view.setCurrentIndex(idx);
       
   849                 if (offset != sb->value()) {
       
   850                     // If it has scrolled, it should have scrolled only by one.
       
   851                     QCOMPARE(sb->value(), offset + 1);
       
   852                     ++offset;
       
   853                 }
       
   854                 //QTest::qWait(50);
       
   855             }
       
   856 
       
   857             --i;    // item 20 does not exist
       
   858             // and then "scroll" up, verify that we scroll one step at a time
       
   859             for (; i >= 0; --i) {
       
   860                 QModelIndex idx = model.index(i,0);
       
   861                 view.setCurrentIndex(idx);
       
   862                 if (offset != sb->value()) {
       
   863                     // If it has scrolled, it should have scrolled only by one.
       
   864                     QCOMPARE(sb->value(), offset - 1);
       
   865                     --offset;
       
   866                 }
       
   867                 //QTest::qWait(50);
       
   868             }
       
   869         }
       
   870     }
       
   871 }
       
   872 
       
   873 class PublicListView : public QListView
       
   874 {
       
   875     public:
       
   876     PublicListView(QWidget *parent = 0) : QListView(parent)
       
   877     {
       
   878 
       
   879     }
       
   880     void setSelection(const QRect &rect, QItemSelectionModel::SelectionFlags flags) {
       
   881         QListView::setSelection(rect, flags);
       
   882     }
       
   883     QSize contentsSize() const { return QListView::contentsSize(); }
       
   884 
       
   885     void setPositionForIndex(const QPoint &pos, const QModelIndex &index) {
       
   886         QListView::setPositionForIndex(pos, index);
       
   887     }
       
   888 };
       
   889 
       
   890 class TestDelegate : public QItemDelegate
       
   891 {
       
   892 public:
       
   893     TestDelegate(QObject *parent) : QItemDelegate(parent), m_sizeHint(50,50) {}
       
   894     QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const { return m_sizeHint; }
       
   895 
       
   896     QSize m_sizeHint;
       
   897 };
       
   898 
       
   899 typedef QList<int> IntList;
       
   900 Q_DECLARE_METATYPE(IntList)
       
   901 
       
   902 void tst_QListView::selection_data()
       
   903 {
       
   904     QTest::addColumn<int>("itemCount");
       
   905     QTest::addColumn<int>("viewMode");
       
   906     QTest::addColumn<int>("flow");
       
   907     QTest::addColumn<bool>("wrapping");
       
   908     QTest::addColumn<int>("spacing");
       
   909     QTest::addColumn<QSize>("gridSize");
       
   910     QTest::addColumn<IntList>("hiddenRows");
       
   911     QTest::addColumn<QRect>("selectionRect");
       
   912     QTest::addColumn<IntList>("expectedItems");
       
   913 
       
   914     QTest::newRow("select all")
       
   915         << 4                                    // itemCount
       
   916         << int(QListView::ListMode)
       
   917         << int(QListView::TopToBottom)
       
   918         << false                                // wrapping
       
   919         << 0                                    // spacing
       
   920         << QSize()                              // gridSize
       
   921         << IntList()                            // hiddenRows
       
   922         << QRect(0, 0, 10, 200)                 // selection rectangle
       
   923         << (IntList() << 0 << 1 << 2 << 3);     // expected items
       
   924 
       
   925     QTest::newRow("select below, (on viewport)")
       
   926         << 4                                    // itemCount
       
   927         << int(QListView::ListMode)
       
   928         << int(QListView::TopToBottom)
       
   929         << false                                // wrapping
       
   930         << 0                                    // spacing
       
   931         << QSize()                              // gridSize
       
   932         << IntList()                            // hiddenRows
       
   933         << QRect(10, 250, 1, 1)                 // selection rectangle
       
   934         << IntList();                           // expected items
       
   935 
       
   936     QTest::newRow("select below 2, (on viewport)")
       
   937         << 4                                    // itemCount
       
   938         << int(QListView::ListMode)
       
   939         << int(QListView::TopToBottom)
       
   940         << true                                 // wrapping
       
   941         << 0                                    // spacing
       
   942         << QSize()                              // gridSize
       
   943         << IntList()                            // hiddenRows
       
   944         << QRect(10, 250, 1, 1)                 // selection rectangle
       
   945         << IntList();                           // expected items
       
   946 
       
   947     QTest::newRow("select to the right, (on viewport)")
       
   948         << 40                                   // itemCount
       
   949         << int(QListView::ListMode)
       
   950         << int(QListView::TopToBottom)
       
   951         << true                                 // wrapping
       
   952         << 0                                    // spacing
       
   953         << QSize()                              // gridSize
       
   954         << IntList()                            // hiddenRows
       
   955         << QRect(300, 10, 1, 1)                 // selection rectangle
       
   956         << IntList();                           // expected items
       
   957 
       
   958     QTest::newRow("select to the right, (on viewport)")
       
   959         << 40                                   // itemCount
       
   960         << int(QListView::ListMode)
       
   961         << int(QListView::TopToBottom)
       
   962         << true                                 // wrapping
       
   963         << 0                                    // spacing
       
   964         << QSize()                              // gridSize
       
   965         << IntList()                            // hiddenRows
       
   966         << QRect(300, 0, 1, 300)                // selection rectangle
       
   967         << IntList();                           // expected items
       
   968 
       
   969 #if defined(Q_OS_WINCE)
       
   970     // depending on wether the display is double-pixeld, we need
       
   971     // to click at a different position
       
   972     bool doubledSize = false;
       
   973     int dpi = GetDeviceCaps(GetDC(0), LOGPIXELSX);
       
   974     if ((dpi < 1000) && (dpi > 0)) {
       
   975         doubledSize = true;
       
   976     }
       
   977     QTest::newRow("select inside contents, (on viewport)")
       
   978         << 35                                   // itemCount
       
   979         << int(QListView::ListMode)
       
   980         << int(QListView::TopToBottom)
       
   981         << true                                 // wrapping
       
   982         << 0                                    // spacing
       
   983         << QSize()                              // gridSize
       
   984         << IntList()                            // hiddenRows
       
   985         << QRect(doubledSize?350:175,doubledSize?550:275, 1, 1)// selection rectangle
       
   986         << IntList();                           // expected items
       
   987 #else
       
   988     QTest::newRow("select inside contents, (on viewport)")
       
   989         << 35                                   // itemCount
       
   990         << int(QListView::ListMode)
       
   991         << int(QListView::TopToBottom)
       
   992         << true                                 // wrapping
       
   993         << 0                                    // spacing
       
   994         << QSize()                              // gridSize
       
   995         << IntList()                            // hiddenRows
       
   996         << QRect(175, 275, 1, 1)                // selection rectangle
       
   997         << IntList();                           // expected items
       
   998 #endif
       
   999 
       
  1000     QTest::newRow("select a tall rect in LeftToRight flow, wrap items")
       
  1001         << 70                                   // itemCount
       
  1002         << int(QListView::ListMode)
       
  1003         << int(QListView::LeftToRight)
       
  1004         << true                                 // wrapping
       
  1005         << 0                                    // spacing
       
  1006         << QSize()                              // gridSize
       
  1007         << IntList()                            // hiddenRows
       
  1008         << QRect(90, 90, 1, 100)                // selection rectangle
       
  1009         << (IntList()                           // expected items
       
  1010                       << 11 << 12 << 13 << 14 << 15 << 16 << 17 << 18 << 19
       
  1011                 << 20 << 21 << 22 << 23 << 24 << 25 << 26 << 27 << 28 << 29
       
  1012                 << 30 << 31);
       
  1013 
       
  1014     QTest::newRow("select a wide rect in LeftToRight, wrap items")
       
  1015         << 70                                   // itemCount
       
  1016         << int(QListView::ListMode)
       
  1017         << int(QListView::LeftToRight)
       
  1018         << true                                 // wrapping
       
  1019         << 0                                    // spacing
       
  1020         << QSize()                              // gridSize
       
  1021         << IntList()                            // hiddenRows
       
  1022         << QRect(90, 90, 200, 1)                // selection rectangle
       
  1023         << (IntList()                           // expected items
       
  1024                       << 11 << 12 << 13 << 14 << 15);
       
  1025 
       
  1026     QTest::newRow("select a wide negative rect in LeftToRight flow, wrap items")
       
  1027         << 70                                   // itemCount
       
  1028         << int(QListView::ListMode)
       
  1029         << int(QListView::LeftToRight)
       
  1030         << true                                 // wrapping
       
  1031         << 0                                    // spacing
       
  1032         << QSize()                              // gridSize
       
  1033         << IntList()                            // hiddenRows
       
  1034         << QRect(290, 90, -200, 1)              // selection rectangle
       
  1035         << (IntList()                           // expected items
       
  1036                       << 11 << 12 << 13 << 14 << 15);
       
  1037 
       
  1038     QTest::newRow("select a tall rect in TopToBottom flow, wrap items")
       
  1039         << 70                                   // itemCount
       
  1040         << int(QListView::ListMode)
       
  1041         << int(QListView::TopToBottom)
       
  1042         << true                                 // wrapping
       
  1043         << 0                                    // spacing
       
  1044         << QSize()                              // gridSize
       
  1045         << IntList()                            // hiddenRows
       
  1046         << QRect(90, 90, 1, 100)                // selection rectangle
       
  1047         << (IntList()                           // expected items
       
  1048                       << 11
       
  1049                       << 12
       
  1050                       << 13);
       
  1051 
       
  1052     QTest::newRow("select a tall negative rect in TopToBottom flow, wrap items")
       
  1053         << 70                                   // itemCount
       
  1054         << int(QListView::ListMode)
       
  1055         << int(QListView::TopToBottom)
       
  1056         << true                                 // wrapping
       
  1057         << 0                                    // spacing
       
  1058         << QSize()                              // gridSize
       
  1059         << IntList()                            // hiddenRows
       
  1060         << QRect(90, 190, 1, -100)              // selection rectangle
       
  1061         << (IntList()                           // expected items
       
  1062                       << 11
       
  1063                       << 12
       
  1064                       << 13);
       
  1065 
       
  1066     QTest::newRow("select a wide rect in TopToBottom, wrap items")
       
  1067         << 70                                   // itemCount
       
  1068         << int(QListView::ListMode)
       
  1069         << int(QListView::TopToBottom)
       
  1070         << true                                 // wrapping
       
  1071         << 0                                    // spacing
       
  1072         << QSize()                              // gridSize
       
  1073         << IntList()                            // hiddenRows
       
  1074         << QRect(90, 90, 100, 1)                // selection rectangle
       
  1075         << (IntList()                           // expected items
       
  1076                             << 20 << 30
       
  1077                       << 11 << 21 << 31
       
  1078                       << 12 << 22
       
  1079                       << 13 << 23
       
  1080                       << 14 << 24
       
  1081                       << 15 << 25
       
  1082                       << 16 << 26
       
  1083                       << 17 << 27
       
  1084                       << 18 << 28
       
  1085                       << 19 << 29);
       
  1086 }
       
  1087 
       
  1088 void tst_QListView::selection()
       
  1089 {
       
  1090     QFETCH(int, itemCount);
       
  1091     QFETCH(int, viewMode);
       
  1092     QFETCH(int, flow);
       
  1093     QFETCH(bool, wrapping);
       
  1094     QFETCH(int, spacing);
       
  1095     QFETCH(QSize, gridSize);
       
  1096     QFETCH(IntList, hiddenRows);
       
  1097     QFETCH(QRect, selectionRect);
       
  1098     QFETCH(IntList, expectedItems);
       
  1099 
       
  1100     PublicListView v;
       
  1101     QtTestModel model;
       
  1102     model.colCount = 1;
       
  1103     model.rCount = itemCount;
       
  1104 
       
  1105     // avoid scrollbar size mismatches among different styles
       
  1106     v.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1107     v.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
       
  1108 
       
  1109     v.setItemDelegate(new TestDelegate(&v));
       
  1110     v.setModel(&model);
       
  1111     v.setViewMode(QListView::ViewMode(viewMode));
       
  1112     v.setFlow(QListView::Flow(flow));
       
  1113     v.setWrapping(wrapping);
       
  1114     v.setResizeMode(QListView::Adjust);
       
  1115     v.setSpacing(spacing);
       
  1116     if (gridSize.isValid())
       
  1117         v.setGridSize(gridSize);
       
  1118     for (int j = 0; j < hiddenRows.count(); ++j) {
       
  1119         v.setRowHidden(hiddenRows.at(j), true);
       
  1120     }
       
  1121 
       
  1122 #if defined(Q_OS_WINCE)
       
  1123     // If the device is double-pixeled then the scrollbars become
       
  1124     // 10 pixels wider than normal (Windows Style: 16, Windows Mobile Style: 26).
       
  1125     // So we have to make the window slightly bigger to have the same count of
       
  1126     // items in each row of the list view like in the other styles.
       
  1127     static const int dpi = ::GetDeviceCaps(GetDC(0), LOGPIXELSX);
       
  1128     if ((dpi < 1000) && (dpi > 0))
       
  1129         v.resize(535,535);
       
  1130 #else
       
  1131     v.resize(525,525);
       
  1132 #endif
       
  1133 
       
  1134     v.show();
       
  1135     QApplication::processEvents();
       
  1136 
       
  1137     v.setSelection(selectionRect, QItemSelectionModel::ClearAndSelect);
       
  1138 
       
  1139     QModelIndexList selected = v.selectionModel()->selectedIndexes();
       
  1140 
       
  1141     QCOMPARE(selected.count(), expectedItems.count());
       
  1142     for (int i = 0; i < selected.count(); ++i) {
       
  1143         QVERIFY(expectedItems.contains(selected.at(i).row()));
       
  1144     }
       
  1145 
       
  1146 }
       
  1147 
       
  1148 void tst_QListView::scrollTo()
       
  1149 {
       
  1150     QListView lv;
       
  1151     QStringListModel model(&lv);
       
  1152     QStringList list;
       
  1153     list << "Short item 1";
       
  1154     list << "Short item 2";
       
  1155     list << "Short item 3";
       
  1156     list << "Short item 4";
       
  1157     list << "Short item 5";
       
  1158     list << "Short item 6";
       
  1159     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"
       
  1160             "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"
       
  1161             "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"
       
  1162             "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"
       
  1163             "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"
       
  1164             "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"
       
  1165             "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"
       
  1166             "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"
       
  1167             "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"
       
  1168             "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"
       
  1169             "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"
       
  1170             "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"
       
  1171             "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"
       
  1172             "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"
       
  1173             "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"
       
  1174             "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";
       
  1175     list << "Short item";
       
  1176     list << "Short item";
       
  1177     list << "Short item";
       
  1178     list << "Short item";
       
  1179     list << "Short item";
       
  1180     list << "Short item";
       
  1181     list << "Short item";
       
  1182     list << "Short item";
       
  1183     model.setStringList(list);
       
  1184     lv.setModel(&model);
       
  1185     lv.setFixedSize(100, 200);
       
  1186     lv.show();
       
  1187 
       
  1188     //by default, the list view scrolls per item and has no wrapping
       
  1189     QModelIndex index = model.index(6,0);
       
  1190 
       
  1191     //we save the size of the item for later comparisons
       
  1192     const QSize itemsize = lv.visualRect(index).size();
       
  1193     QVERIFY(itemsize.height() > lv.height());
       
  1194     QVERIFY(itemsize.width() > lv.width());
       
  1195 
       
  1196     //we click the item
       
  1197     QPoint p = lv.visualRect(index).center();
       
  1198     QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  1199     //let's wait 1 second because the scrolling is delayed
       
  1200     QTest::qWait(1000);
       
  1201     QCOMPARE(lv.visualRect(index).y(),0);
       
  1202 
       
  1203     //we scroll down. As the item is to tall for the view, it will disappear
       
  1204     QTest::keyClick(lv.viewport(), Qt::Key_Down, Qt::NoModifier);
       
  1205     QCOMPARE(lv.visualRect(index).y(), -itemsize.height());
       
  1206 
       
  1207     QTest::keyClick(lv.viewport(), Qt::Key_Up, Qt::NoModifier);
       
  1208     QCOMPARE(lv.visualRect(index).y(), 0);
       
  1209 
       
  1210     //Let's enable wrapping
       
  1211 
       
  1212     lv.setWrapping(true);
       
  1213     lv.horizontalScrollBar()->setValue(0); //let's scroll to the beginning
       
  1214 
       
  1215     //we click the item
       
  1216     p = lv.visualRect(index).center();
       
  1217     QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  1218     //let's wait 1 second because the scrolling is delayed
       
  1219     QTest::qWait(1000);
       
  1220     QCOMPARE(lv.visualRect(index).x(),0);
       
  1221 
       
  1222     //we scroll right. As the item is too wide for the view, it will disappear
       
  1223     QTest::keyClick(lv.viewport(), Qt::Key_Right, Qt::NoModifier);
       
  1224     QCOMPARE(lv.visualRect(index).x(), -itemsize.width());
       
  1225 
       
  1226     QTest::keyClick(lv.viewport(), Qt::Key_Left, Qt::NoModifier);
       
  1227     QCOMPARE(lv.visualRect(index).x(), 0);
       
  1228 
       
  1229     lv.setWrapping(false);
       
  1230     qApp->processEvents(); //let the layout happen
       
  1231 
       
  1232     //Let's try with scrolling per pixel
       
  1233     lv.setHorizontalScrollMode( QListView::ScrollPerPixel);
       
  1234     lv.verticalScrollBar()->setValue(0); //scrolls back to the first item
       
  1235 
       
  1236     //we click the item
       
  1237     p = lv.visualRect(index).center();
       
  1238     QTest::mouseClick(lv.viewport(), Qt::LeftButton, Qt::NoModifier, p);
       
  1239     //let's wait 1 second because the scrolling is delayed
       
  1240     QTest::qWait(1000);
       
  1241     QCOMPARE(lv.visualRect(index).y(),0);
       
  1242 
       
  1243     //we scroll down. As the item is too tall for the view, it will partially disappear
       
  1244     QTest::keyClick(lv.viewport(), Qt::Key_Down, Qt::NoModifier);
       
  1245     QVERIFY(lv.visualRect(index).y()<0);
       
  1246 
       
  1247     QTest::keyClick(lv.viewport(), Qt::Key_Up, Qt::NoModifier);
       
  1248     QCOMPARE(lv.visualRect(index).y(), 0);
       
  1249 
       
  1250 }
       
  1251 
       
  1252 
       
  1253 void tst_QListView::scrollBarRanges()
       
  1254 {
       
  1255     const int rowCount = 10;
       
  1256     const int rowHeight = 20;
       
  1257 
       
  1258     QListView lv;
       
  1259     QStringListModel model(&lv);
       
  1260     QStringList list;
       
  1261     for (int i = 0; i < rowCount; ++i)
       
  1262         list << QString::fromAscii("Item %1").arg(i);
       
  1263 
       
  1264     model.setStringList(list);
       
  1265     lv.setModel(&model);
       
  1266     lv.resize(250, 130);
       
  1267     TestDelegate *delegate = new TestDelegate(&lv);
       
  1268     delegate->m_sizeHint = QSize(100, rowHeight);
       
  1269     lv.setItemDelegate(delegate);
       
  1270     lv.show();
       
  1271 
       
  1272     for (int h = 30; h <= 210; ++h) {
       
  1273         lv.resize(250, h);
       
  1274         QTest::qWait(100); // wait for the layout to be done
       
  1275         int visibleRowCount = lv.viewport()->size().height() / rowHeight;
       
  1276         int invisibleRowCount = rowCount - visibleRowCount;
       
  1277         QCOMPARE(lv.verticalScrollBar()->maximum(), invisibleRowCount);
       
  1278     }
       
  1279 }
       
  1280 
       
  1281 void tst_QListView::scrollBarAsNeeded_data()
       
  1282 {
       
  1283     QTest::addColumn<QSize>("size");
       
  1284     QTest::addColumn<int>("itemCount");
       
  1285     QTest::addColumn<int>("flow");
       
  1286     QTest::addColumn<bool>("horizontalScrollBarVisible");
       
  1287     QTest::addColumn<bool>("verticalScrollBarVisible");
       
  1288 
       
  1289 
       
  1290     QTest::newRow("TopToBottom, count:0")
       
  1291             << QSize(200, 100)
       
  1292             << 0
       
  1293             << int(QListView::TopToBottom)
       
  1294             << false
       
  1295             << false;
       
  1296 
       
  1297     QTest::newRow("TopToBottom, count:1")
       
  1298             << QSize(200, 100)
       
  1299             << 1
       
  1300             << int(QListView::TopToBottom)
       
  1301             << false
       
  1302             << false;
       
  1303 
       
  1304     QTest::newRow("TopToBottom, count:20")
       
  1305             << QSize(200, 100)
       
  1306             << 20
       
  1307             << int(QListView::TopToBottom)
       
  1308             << false
       
  1309             << true;
       
  1310 
       
  1311     QTest::newRow("LeftToRight, count:0")
       
  1312             << QSize(200, 100)
       
  1313             << 0
       
  1314             << int(QListView::LeftToRight)
       
  1315             << false
       
  1316             << false;
       
  1317 
       
  1318     QTest::newRow("LeftToRight, count:1")
       
  1319             << QSize(200, 100)
       
  1320             << 1
       
  1321             << int(QListView::LeftToRight)
       
  1322             << false
       
  1323             << false;
       
  1324 
       
  1325     QTest::newRow("LeftToRight, count:20")
       
  1326             << QSize(200, 100)
       
  1327             << 20
       
  1328             << int(QListView::LeftToRight)
       
  1329             << true
       
  1330             << false;
       
  1331 
       
  1332 
       
  1333 }
       
  1334 void tst_QListView::scrollBarAsNeeded()
       
  1335 {
       
  1336 
       
  1337     QFETCH(QSize, size);
       
  1338     QFETCH(int, itemCount);
       
  1339     QFETCH(int, flow);
       
  1340     QFETCH(bool, horizontalScrollBarVisible);
       
  1341     QFETCH(bool, verticalScrollBarVisible);
       
  1342 
       
  1343 
       
  1344     const int rowCounts[3] = {0, 1, 20};
       
  1345 
       
  1346     QListView lv;
       
  1347     lv.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       
  1348     lv.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       
  1349     lv.setFlow((QListView::Flow)flow);
       
  1350     QStringListModel model(&lv);
       
  1351     lv.setModel(&model);
       
  1352     lv.resize(size);
       
  1353     lv.show();
       
  1354 
       
  1355     for (uint r = 0; r < sizeof(rowCounts)/sizeof(int); ++r) {
       
  1356         QStringList list;
       
  1357         int i;
       
  1358         for (i = 0; i < rowCounts[r]; ++i)
       
  1359             list << QString::fromAscii("Item %1").arg(i);
       
  1360 
       
  1361         model.setStringList(list);
       
  1362         QApplication::processEvents();
       
  1363         QTest::qWait(100);
       
  1364 
       
  1365         QStringList replacement;
       
  1366         for (i = 0; i < itemCount; ++i) {
       
  1367             replacement << QString::fromAscii("Item %1").arg(i);
       
  1368         }
       
  1369         model.setStringList(replacement);
       
  1370 
       
  1371         QApplication::processEvents();
       
  1372         QTest::qWait(100);
       
  1373 
       
  1374         QCOMPARE(lv.horizontalScrollBar()->isVisible(), horizontalScrollBarVisible);
       
  1375         QCOMPARE(lv.verticalScrollBar()->isVisible(), verticalScrollBarVisible);
       
  1376     }
       
  1377 }
       
  1378 
       
  1379 void tst_QListView::moveItems()
       
  1380 {
       
  1381     QStandardItemModel model;
       
  1382     for (int r = 0; r < 4; ++r) {
       
  1383         for (int c = 0; c < 4; ++c) {
       
  1384             QStandardItem* item = new QStandardItem(QString("standard item (%1,%2)").arg(r).arg(c));
       
  1385             model.setItem(r, c, item);
       
  1386         }
       
  1387     }
       
  1388 
       
  1389     PublicListView view;
       
  1390     view.setViewMode(QListView::IconMode);
       
  1391     view.setResizeMode(QListView::Fixed);
       
  1392     view.setWordWrap(true);
       
  1393     view.setModel(&model);
       
  1394     view.setItemDelegate(new TestDelegate(&view));
       
  1395 
       
  1396     for (int r = 0; r < model.rowCount(); ++r) {
       
  1397         for (int c = 0; c < model.columnCount(); ++c) {
       
  1398             const QModelIndex& idx = model.index(r, c);
       
  1399             view.setPositionForIndex(QPoint(r * 75, r * 75), idx);
       
  1400         }
       
  1401     }
       
  1402 
       
  1403     QCOMPARE(view.contentsSize(), QSize(275, 275));
       
  1404 }
       
  1405 
       
  1406 void tst_QListView::wordWrap()
       
  1407 {
       
  1408     QListView lv;
       
  1409     lv.setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       
  1410     lv.setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
       
  1411     QStringListModel model(&lv);
       
  1412     QStringList list;
       
  1413     list << "Short item 1";
       
  1414     list << "Short item 2";
       
  1415     list << "Short item 3";
       
  1416     list << "Begin\nThis item take severals Lines\nEnd";
       
  1417     list << "And this is a very long item very long item this is a very vary vary long item"
       
  1418             "very long very very long long long this is a long item a very long item a very very long item";
       
  1419     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"
       
  1420             "very long very very long long long this is a long item a very long item a very very long item";
       
  1421     list << "Short item";
       
  1422     list << "rzeofig zerig fslfgj smdlfkgj qmsdlfj amrzriougf qsla zrg fgsdf gsdfg sdfgs dfg sdfgcvb sdfg qsdjfh qsdfjklh qs";
       
  1423     list << "Short item";
       
  1424     model.setStringList(list);
       
  1425     lv.setModel(&model);
       
  1426     lv.setWordWrap(true);
       
  1427     lv.setFixedSize(150, 150);
       
  1428     lv.show();
       
  1429     QApplication::processEvents();
       
  1430     QTest::qWait(100);
       
  1431 
       
  1432     QCOMPARE(lv.horizontalScrollBar()->isVisible(), false);
       
  1433     QCOMPARE(lv.verticalScrollBar()->isVisible(), true);
       
  1434 }
       
  1435 
       
  1436 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
       
  1437 class SetCurrentIndexAfterAppendRowCrashDialog : public QDialog
       
  1438 {
       
  1439     Q_OBJECT
       
  1440 public:
       
  1441     SetCurrentIndexAfterAppendRowCrashDialog()
       
  1442     {
       
  1443 #if WINVER >= 0x0500
       
  1444         listView = new QListView();
       
  1445         listView->setViewMode(QListView::IconMode);
       
  1446 
       
  1447         model = new QStandardItemModel(this);
       
  1448         listView->setModel(model);
       
  1449 
       
  1450         timer = new QTimer(this);
       
  1451         connect(timer, SIGNAL(timeout()), this, SLOT(buttonClicked()));
       
  1452         timer->start(1000);
       
  1453 
       
  1454         DWORD lParam = 0xFFFFFFFC/*OBJID_CLIENT*/;
       
  1455         DWORD wParam = 0;
       
  1456         SendMessage(winId(), WM_GETOBJECT, wParam, lParam);
       
  1457 #endif
       
  1458     }
       
  1459 
       
  1460 private slots:
       
  1461     void buttonClicked()
       
  1462     {
       
  1463         timer->stop();
       
  1464         QStandardItem *item = new QStandardItem("test");
       
  1465         model->appendRow(item);
       
  1466         listView->setCurrentIndex(model->indexFromItem(item));
       
  1467         close();
       
  1468     }
       
  1469 private:
       
  1470     QListView *listView;
       
  1471     QStandardItemModel *model;
       
  1472     QTimer *timer;
       
  1473 };
       
  1474 #endif
       
  1475 
       
  1476 void tst_QListView::setCurrentIndexAfterAppendRowCrash()
       
  1477 {
       
  1478 #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && WINVER >= 0x0500
       
  1479     SetCurrentIndexAfterAppendRowCrashDialog w;
       
  1480     w.exec();
       
  1481 #else
       
  1482     QSKIP("This test only makes sense on windows 2000 and higher.", SkipAll);
       
  1483 #endif
       
  1484 }
       
  1485 
       
  1486 void tst_QListView::emptyItemSize()
       
  1487 {
       
  1488     QStandardItemModel model;
       
  1489     for (int r = 0; r < 4; ++r) {
       
  1490         QStandardItem* item = new QStandardItem(QString("standard item (%1)").arg(r));
       
  1491         model.setItem(r, 0, item);
       
  1492     }
       
  1493     model.setItem(4, 0, new QStandardItem());
       
  1494 
       
  1495     PublicListView view;
       
  1496     view.setModel(&model);
       
  1497 
       
  1498     for (int i = 0; i < 5; ++i)
       
  1499         QVERIFY(!view.visualRect(model.index(i, 0)).isEmpty());
       
  1500 }
       
  1501 
       
  1502 void tst_QListView::task203585_selectAll()
       
  1503 {
       
  1504     //we make sure that "select all" doesn't select the hidden items
       
  1505     QListView view;
       
  1506     view.setSelectionMode(QAbstractItemView::ExtendedSelection);
       
  1507     view.setModel(new QStringListModel( QStringList() << "foo"));
       
  1508     view.setRowHidden(0, true);
       
  1509     view.selectAll();
       
  1510     QVERIFY(view.selectionModel()->selectedIndexes().isEmpty());
       
  1511     view.setRowHidden(0, false);
       
  1512     view.selectAll();
       
  1513     QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
       
  1514 }
       
  1515 
       
  1516 void tst_QListView::task228566_infiniteRelayout()
       
  1517 {
       
  1518     QListView view;
       
  1519 
       
  1520     QStringList list;
       
  1521     for (int i = 0; i < 10; ++i) {
       
  1522         list << "small";
       
  1523     }
       
  1524 
       
  1525     list << "BIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIG";
       
  1526     list << "BIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIGBIG";
       
  1527 
       
  1528     QStringListModel model(list);
       
  1529     view.setModel(&model);
       
  1530     view.setWrapping(true);
       
  1531     view.setResizeMode(QListView::Adjust);
       
  1532 
       
  1533     const int itemHeight = view.visualRect( model.index(0, 0)).height();
       
  1534 
       
  1535     view.setFixedHeight(itemHeight * 12);
       
  1536     view.show();
       
  1537     QTest::qWait(100); //make sure the layout is done once
       
  1538 
       
  1539     QSignalSpy spy(view.horizontalScrollBar(), SIGNAL(rangeChanged(int, int)));
       
  1540 
       
  1541     QTest::qWait(200);
       
  1542     //the layout should already have been done
       
  1543     //so there should be no change made to the scrollbar
       
  1544     QCOMPARE(spy.count(), 0);
       
  1545 }
       
  1546 
       
  1547 void tst_QListView::task248430_crashWith0SizedItem()
       
  1548 {
       
  1549     QListView view;
       
  1550     view.setViewMode(QListView::IconMode);
       
  1551     QStringListModel model(QStringList() << QLatin1String("item1") << QString());
       
  1552     view.setModel(&model);
       
  1553     view.show();
       
  1554     QTest::qWait(100);
       
  1555 }
       
  1556 
       
  1557 void tst_QListView::task250446_scrollChanged()
       
  1558 {
       
  1559     QStandardItemModel model(200, 1);
       
  1560     QListView view;
       
  1561     view.setModel(&model);
       
  1562     QModelIndex index = model.index(0, 0);
       
  1563     QVERIFY(index.isValid());
       
  1564     view.setCurrentIndex(index);
       
  1565     view.show();
       
  1566     QTest::qWait(100);
       
  1567     const int scrollValue = view.verticalScrollBar()->maximum();
       
  1568     view.verticalScrollBar()->setValue(scrollValue);
       
  1569     QCOMPARE(view.verticalScrollBar()->value(), scrollValue);
       
  1570     QCOMPARE(view.currentIndex(), index);
       
  1571 
       
  1572     view.showMinimized();
       
  1573     QTest::qWait(100);
       
  1574     QCOMPARE(view.verticalScrollBar()->value(), scrollValue);
       
  1575     QCOMPARE(view.currentIndex(), index);
       
  1576 
       
  1577     view.showNormal();
       
  1578     QTest::qWait(100);
       
  1579     QCOMPARE(view.verticalScrollBar()->value(), scrollValue);
       
  1580     QCOMPARE(view.currentIndex(), index);
       
  1581 }
       
  1582 
       
  1583 void tst_QListView::task196118_visualRegionForSelection()
       
  1584 {
       
  1585     class MyListView : public QListView
       
  1586     {
       
  1587     public:
       
  1588         QRegion visualRegionForSelection() const
       
  1589         { return QListView::visualRegionForSelection( selectionModel()->selection()); }
       
  1590     } view;
       
  1591 
       
  1592     QStandardItemModel model;
       
  1593     QStandardItem top1("top1");
       
  1594     QStandardItem sub1("sub1");
       
  1595     top1.appendRow(QList<QStandardItem*>() << &sub1);
       
  1596     model.appendColumn(QList<QStandardItem*>() << &top1);
       
  1597     view.setModel(&model);
       
  1598     view.setRootIndex(top1.index());
       
  1599 
       
  1600     view.selectionModel()->select(top1.index(), QItemSelectionModel::Select);
       
  1601 
       
  1602     QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
       
  1603     QVERIFY(view.visualRegionForSelection().isEmpty());
       
  1604 }
       
  1605 
       
  1606 void tst_QListView::task254449_draggingItemToNegativeCoordinates()
       
  1607 {
       
  1608     //we'll check that the items are painted correctly
       
  1609     class MyListView : public QListView
       
  1610     {
       
  1611     public:
       
  1612         void setPositionForIndex(const QPoint &position, const QModelIndex &index)
       
  1613         { QListView::setPositionForIndex(position, index); }
       
  1614 
       
  1615     } list;
       
  1616 
       
  1617     QStandardItemModel model(1,1);
       
  1618     QModelIndex index = model.index(0,0);
       
  1619     model.setData(index, QLatin1String("foo"));
       
  1620     list.setModel(&model);
       
  1621     list.setViewMode(QListView::IconMode);
       
  1622     list.show();
       
  1623     QTest::qWaitForWindowShown(&list);
       
  1624 
       
  1625     class MyItemDelegate : public QStyledItemDelegate
       
  1626     {
       
  1627     public:
       
  1628         MyItemDelegate() : numPaints(0) { }
       
  1629         void paint(QPainter *painter,
       
  1630                const QStyleOptionViewItem &option, const QModelIndex &index) const
       
  1631         {
       
  1632             numPaints++;
       
  1633             QStyledItemDelegate::paint(painter, option, index);
       
  1634         }
       
  1635 
       
  1636         mutable int numPaints;
       
  1637     } delegate;
       
  1638     delegate.numPaints = 0;
       
  1639     list.setItemDelegate(&delegate);
       
  1640     QApplication::processEvents();
       
  1641     QTRY_VERIFY(delegate.numPaints > 0);  //makes sure the layout is done
       
  1642 
       
  1643     const QPoint topLeft(-6, 0);
       
  1644     list.setPositionForIndex(topLeft, index);
       
  1645 
       
  1646     //we'll make sure the item is repainted
       
  1647     delegate.numPaints = 0;
       
  1648     QApplication::processEvents();
       
  1649     QCOMPARE(list.visualRect(index).topLeft(), topLeft);
       
  1650     QCOMPARE(delegate.numPaints, 1);
       
  1651 }
       
  1652 
       
  1653 
       
  1654 void tst_QListView::keyboardSearch()
       
  1655 {
       
  1656     QStringList items;
       
  1657     items << "AB" << "AC" << "BA" << "BB" << "BD" << "KAFEINE" << "KONQUEROR" << "KOPETE" << "KOOKA" << "OKULAR";
       
  1658     QStringListModel model(items);
       
  1659 
       
  1660     QListView view;
       
  1661     view.setModel(&model);
       
  1662     view.show();
       
  1663     QTest::qWait(30);
       
  1664 //    QCOMPARE(view.currentIndex() , model.index(0,0));
       
  1665 
       
  1666     QTest::keyClick(&view, Qt::Key_K);
       
  1667     QTest::qWait(10);
       
  1668     QCOMPARE(view.currentIndex() , model.index(5,0)); //KAFEINE
       
  1669 
       
  1670     QTest::keyClick(&view, Qt::Key_O);
       
  1671     QTest::qWait(10);
       
  1672     QCOMPARE(view.currentIndex() , model.index(6,0)); //KONQUEROR
       
  1673 
       
  1674     QTest::keyClick(&view, Qt::Key_N);
       
  1675     QTest::qWait(10);
       
  1676     QCOMPARE(view.currentIndex() , model.index(6,0)); //KONQUEROR
       
  1677 }
       
  1678 
       
  1679 void tst_QListView::shiftSelectionWithNonUniformItemSizes()
       
  1680 {
       
  1681     // This checks that no items are selected unexpectedly by Shift-Arrow
       
  1682     // when items with non-uniform sizes are laid out in a grid
       
  1683     {   // First test: QListView::LeftToRight flow
       
  1684         QStringList items;
       
  1685         items << "Long\nText" << "Text" << "Text" << "Text";
       
  1686         QStringListModel model(items);
       
  1687 
       
  1688         QListView view;
       
  1689         view.setFixedSize(250, 250);
       
  1690         view.setFlow(QListView::LeftToRight);
       
  1691         view.setGridSize(QSize(100, 100));
       
  1692         view.setSelectionMode(QListView::ExtendedSelection);
       
  1693         view.setViewMode(QListView::IconMode);
       
  1694         view.setModel(&model);
       
  1695         view.show();
       
  1696         QTest::qWait(30);
       
  1697 
       
  1698         // Verfify that item sizes are non-uniform
       
  1699         QVERIFY(view.sizeHintForIndex(model.index(0, 0)).height() > view.sizeHintForIndex(model.index(1, 0)).height());
       
  1700 
       
  1701         QModelIndex index = model.index(3, 0);
       
  1702         view.setCurrentIndex(index);
       
  1703         QCOMPARE(view.currentIndex(), index);
       
  1704 
       
  1705         QTest::keyClick(&view, Qt::Key_Up, Qt::ShiftModifier);
       
  1706         QTest::qWait(10);
       
  1707         QCOMPARE(view.currentIndex(), model.index(1, 0));
       
  1708 
       
  1709         QModelIndexList selected = view.selectionModel()->selectedIndexes();
       
  1710         QCOMPARE(selected.count(), 3);
       
  1711         QVERIFY(!selected.contains(model.index(0, 0)));
       
  1712     }
       
  1713     {   // Second test: QListView::TopToBottom flow
       
  1714         QStringList items;
       
  1715         items << "ab" << "a" << "a" << "a";
       
  1716         QStringListModel model(items);
       
  1717 
       
  1718         QListView view;
       
  1719         view.setFixedSize(250, 250);
       
  1720         view.setFlow(QListView::TopToBottom);
       
  1721         view.setGridSize(QSize(100, 100));
       
  1722         view.setSelectionMode(QListView::ExtendedSelection);
       
  1723         view.setViewMode(QListView::IconMode);
       
  1724         view.setModel(&model);
       
  1725         view.show();
       
  1726         QTest::qWait(30);
       
  1727 
       
  1728         // Verfify that item sizes are non-uniform
       
  1729         QVERIFY(view.sizeHintForIndex(model.index(0, 0)).width() > view.sizeHintForIndex(model.index(1, 0)).width());
       
  1730 
       
  1731         QModelIndex index = model.index(3, 0);
       
  1732         view.setCurrentIndex(index);
       
  1733         QCOMPARE(view.currentIndex(), index);
       
  1734 
       
  1735         QTest::keyClick(&view, Qt::Key_Left, Qt::ShiftModifier);
       
  1736         QTest::qWait(10);
       
  1737         QCOMPARE(view.currentIndex(), model.index(1, 0));
       
  1738 
       
  1739         QModelIndexList selected = view.selectionModel()->selectedIndexes();
       
  1740         QCOMPARE(selected.count(), 3);
       
  1741         QVERIFY(!selected.contains(model.index(0, 0)));
       
  1742     }
       
  1743 }
       
  1744 
       
  1745 void tst_QListView::clickOnViewportClearsSelection()
       
  1746 {
       
  1747     QStringList items;
       
  1748     items << "Text1";
       
  1749     QStringListModel model(items);
       
  1750     QListView view;
       
  1751     view.setModel(&model);
       
  1752     view.setSelectionMode(QListView::ExtendedSelection);
       
  1753 
       
  1754     view.selectAll();
       
  1755     QModelIndex index = model.index(0);
       
  1756     QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
       
  1757     QVERIFY(view.selectionModel()->isSelected(index));
       
  1758 
       
  1759     //we try to click outside of the index
       
  1760     const QPoint point = view.visualRect(index).bottomRight() + QPoint(10,10);
       
  1761 
       
  1762     QTest::mousePress(view.viewport(), Qt::LeftButton, 0, point);
       
  1763     //at this point, the selection shouldn't have changed
       
  1764     QCOMPARE(view.selectionModel()->selectedIndexes().count(), 1);
       
  1765     QVERIFY(view.selectionModel()->isSelected(index));
       
  1766 
       
  1767     QTest::mouseRelease(view.viewport(), Qt::LeftButton, 0, point);
       
  1768     //now the selection should be cleared
       
  1769     QVERIFY(!view.selectionModel()->hasSelection());
       
  1770 
       
  1771 }
       
  1772 
       
  1773 void tst_QListView::task262152_setModelColumnNavigate()
       
  1774 {
       
  1775     QListView view;
       
  1776     QStandardItemModel model(3,2);
       
  1777     model.setItem(0,1,new QStandardItem("[0,1]"));
       
  1778     model.setItem(1,1,new QStandardItem("[1,1]"));
       
  1779     model.setItem(2,1,new QStandardItem("[2,1]"));
       
  1780 
       
  1781     view.setModel(&model);
       
  1782     view.setModelColumn(1);
       
  1783 
       
  1784     view.show();
       
  1785     QTest::qWait(100);
       
  1786     QTest::keyClick(&view, Qt::Key_Down);
       
  1787     QTest::qWait(100);
       
  1788     QCOMPARE(view.currentIndex(), model.index(1,1));
       
  1789     QTest::keyClick(&view, Qt::Key_Down);
       
  1790     QTest::qWait(100);
       
  1791     QCOMPARE(view.currentIndex(), model.index(2,1));
       
  1792 
       
  1793 }
       
  1794 
       
  1795 void tst_QListView::taskQTBUG_2233_scrollHiddenItems_data()
       
  1796 {
       
  1797     QTest::addColumn<int>("flow");
       
  1798 
       
  1799     QTest::newRow("TopToBottom") << static_cast<int>(QListView::TopToBottom);
       
  1800     QTest::newRow("LeftToRight") << static_cast<int>(QListView::LeftToRight);
       
  1801 }
       
  1802 
       
  1803 void tst_QListView::taskQTBUG_2233_scrollHiddenItems()
       
  1804 {
       
  1805     QFETCH(int, flow);
       
  1806     const int rowCount = 200;
       
  1807 
       
  1808     QListView view;
       
  1809     QStringListModel model(&view);
       
  1810     QStringList list;
       
  1811     for (int i = 0; i < rowCount; ++i)
       
  1812         list << QString::fromAscii("Item %1").arg(i);
       
  1813 
       
  1814     model.setStringList(list);
       
  1815     view.setModel(&model);
       
  1816     view.setViewMode(QListView::ListMode);
       
  1817     for (int i = 0; i < rowCount / 2; ++i)
       
  1818         view.setRowHidden(2 * i, true);
       
  1819     view.setFlow(static_cast<QListView::Flow>(flow));
       
  1820     view.resize(130, 130);
       
  1821 
       
  1822     for (int i = 0; i < 10; ++i) {
       
  1823         (view.flow() == QListView::TopToBottom
       
  1824             ? view.verticalScrollBar()
       
  1825             : view.horizontalScrollBar())->setValue(i);
       
  1826         QModelIndex index = view.indexAt(QPoint(0,0));
       
  1827         QVERIFY(index.isValid());
       
  1828         QCOMPARE(index.row(), 2 * i + 1);
       
  1829     }
       
  1830 }
       
  1831 
       
  1832 QTEST_MAIN(tst_QListView)
       
  1833 #include "tst_qlistview.moc"