/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp

https://bitbucket.org/ultra_iter/qt-vtl · C++ · 2713 lines · 2254 code · 329 blank · 130 comment · 91 complexity · 65f361859ee45d048fee8866e318933b MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2012 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. ** GNU Lesser General Public License Usage
  11. ** This file may be used under the terms of the GNU Lesser General Public
  12. ** License version 2.1 as published by the Free Software Foundation and
  13. ** appearing in the file LICENSE.LGPL included in the packaging of this
  14. ** file. Please review the following information to ensure the GNU Lesser
  15. ** General Public License version 2.1 requirements will be met:
  16. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  17. **
  18. ** In addition, as a special exception, Nokia gives you certain additional
  19. ** rights. These rights are described in the Nokia Qt LGPL Exception
  20. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  21. **
  22. ** GNU General Public License Usage
  23. ** Alternatively, this file may be used under the terms of the GNU General
  24. ** Public License version 3.0 as published by the Free Software Foundation
  25. ** and appearing in the file LICENSE.GPL included in the packaging of this
  26. ** file. Please review the following information to ensure the GNU General
  27. ** Public License version 3.0 requirements will be met:
  28. ** http://www.gnu.org/copyleft/gpl.html.
  29. **
  30. ** Other Usage
  31. ** Alternatively, this file may be used in accordance with the terms and
  32. ** conditions contained in a signed written agreement between you and Nokia.
  33. **
  34. **
  35. **
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #include <QtTest/QtTest>
  42. #include <QtGui/QtGui>
  43. //TESTED_CLASS=
  44. //TESTED_FILES=
  45. class tst_QItemSelectionModel : public QObject
  46. {
  47. Q_OBJECT
  48. public:
  49. tst_QItemSelectionModel();
  50. virtual ~tst_QItemSelectionModel();
  51. public slots:
  52. void initTestCase();
  53. void cleanupTestCase();
  54. void init();
  55. private slots:
  56. void clear_data();
  57. void clear();
  58. void clearAndSelect();
  59. void toggleSelection();
  60. void select_data();
  61. void select();
  62. void persistentselections_data();
  63. void persistentselections();
  64. void resetModel();
  65. void removeRows_data();
  66. void removeRows();
  67. void removeColumns_data();
  68. void removeColumns();
  69. void modelLayoutChanged_data();
  70. void modelLayoutChanged();
  71. void selectedRows_data();
  72. void selectedRows();
  73. void selectedColumns_data();
  74. void selectedColumns();
  75. void setCurrentIndex();
  76. void splitOnInsert();
  77. void task196285_rowIntersectsSelection();
  78. void unselectable();
  79. void task220420_selectedIndexes();
  80. void task240734_layoutChanged();
  81. void merge_data();
  82. void merge();
  83. void task119433_isRowSelected();
  84. void task252069_rowIntersectsSelection();
  85. void task232634_childrenDeselectionSignal();
  86. void task260134_layoutChangedWithAllSelected();
  87. void QTBUG5671_layoutChangedWithAllSelected();
  88. void QTBUG2804_layoutChangedTreeSelection();
  89. void deselectRemovedMiddleRange();
  90. void rangeOperatorLessThan_data();
  91. void rangeOperatorLessThan();
  92. void testDifferentModels();
  93. void testValidRangesInSelectionsAfterReset();
  94. void testChainedSelectionClear();
  95. private:
  96. QAbstractItemModel *model;
  97. QItemSelectionModel *selection;
  98. };
  99. QDataStream &operator<<(QDataStream &, const QModelIndex &);
  100. QDataStream &operator>>(QDataStream &, QModelIndex &);
  101. QDataStream &operator<<(QDataStream &, const QModelIndexList &);
  102. QDataStream &operator>>(QDataStream &, QModelIndexList &);
  103. typedef QList<int> IntList;
  104. typedef QPair<int, int> IntPair;
  105. typedef QList<IntPair> PairList;
  106. Q_DECLARE_METATYPE(PairList)
  107. Q_DECLARE_METATYPE(QModelIndex)
  108. Q_DECLARE_METATYPE(QModelIndexList)
  109. Q_DECLARE_METATYPE(IntList)
  110. Q_DECLARE_METATYPE(QItemSelection)
  111. class QStreamHelper: public QAbstractItemModel
  112. {
  113. public:
  114. QStreamHelper() {}
  115. static QModelIndex create(int row = -1, int column = -1, void *data = 0)
  116. {
  117. QStreamHelper helper;
  118. return helper.QAbstractItemModel::createIndex(row, column, data);
  119. }
  120. QModelIndex index(int, int, const QModelIndex&) const
  121. { return QModelIndex(); }
  122. QModelIndex parent(const QModelIndex&) const
  123. { return QModelIndex(); }
  124. int rowCount(const QModelIndex & = QModelIndex()) const
  125. { return 0; }
  126. int columnCount(const QModelIndex & = QModelIndex()) const
  127. { return 0; }
  128. QVariant data(const QModelIndex &, int = Qt::DisplayRole) const
  129. { return QVariant(); }
  130. bool hasChildren(const QModelIndex &) const
  131. { return false; }
  132. };
  133. QDataStream &operator<<(QDataStream &s, const QModelIndex &input)
  134. {
  135. s << input.row()
  136. << input.column()
  137. << reinterpret_cast<qlonglong>(input.internalPointer());
  138. return s;
  139. }
  140. QDataStream &operator>>(QDataStream &s, QModelIndex &output)
  141. {
  142. int r, c;
  143. qlonglong ptr;
  144. s >> r;
  145. s >> c;
  146. s >> ptr;
  147. output = QStreamHelper::create(r, c, reinterpret_cast<void *>(ptr));
  148. return s;
  149. }
  150. QDataStream &operator<<(QDataStream &s, const QModelIndexList &input)
  151. {
  152. s << input.count();
  153. for (int i=0; i<input.count(); ++i)
  154. s << input.at(i);
  155. return s;
  156. }
  157. QDataStream &operator>>(QDataStream &s, QModelIndexList &output)
  158. {
  159. QModelIndex tmpIndex;
  160. int count;
  161. s >> count;
  162. for (int i=0; i<count; ++i) {
  163. s >> tmpIndex;
  164. output << tmpIndex;
  165. }
  166. return s;
  167. }
  168. tst_QItemSelectionModel::tst_QItemSelectionModel() : model(0), selection(0)
  169. {
  170. }
  171. tst_QItemSelectionModel::~tst_QItemSelectionModel()
  172. {
  173. }
  174. /*
  175. This test usually uses a model with a 5x5 table
  176. -------------------------------------------
  177. | 0,0 | 0,1 | 0,2 | 0,3 | 0,4 |
  178. -------------------------------------------
  179. | 1,0 | 1,1 | 1,2 | 1,3 | 1,4 |
  180. -------------------------------------------
  181. | 2,0 | 2,1 | 2,2 | 2,3 | 2,4 |
  182. -------------------------------------------
  183. | 3,0 | 3,1 | 3,2 | 3,3 | 3,4 |
  184. -------------------------------------------
  185. | 4,0 | 4,1 | 4,2 | 4,3 | 4,4 |
  186. -------------------------------------------
  187. ...that for each row has a children in a new 5x5 table ad infinitum.
  188. */
  189. void tst_QItemSelectionModel::initTestCase()
  190. {
  191. qRegisterMetaType<QItemSelection>("QItemSelection");
  192. model = new QStandardItemModel(5, 5);
  193. QModelIndex parent = model->index(0, 0, QModelIndex());
  194. model->insertRows(0, 5, parent);
  195. model->insertColumns(0, 5, parent);
  196. selection = new QItemSelectionModel(model);
  197. }
  198. void tst_QItemSelectionModel::cleanupTestCase()
  199. {
  200. delete selection;
  201. delete model;
  202. }
  203. void tst_QItemSelectionModel::init()
  204. {
  205. selection->clear();
  206. while (model->rowCount(QModelIndex()) > 5)
  207. model->removeRow(0, QModelIndex());
  208. while (model->rowCount(QModelIndex()) < 5)
  209. model->insertRow(0, QModelIndex());
  210. }
  211. void tst_QItemSelectionModel::clear_data()
  212. {
  213. QTest::addColumn<QModelIndexList>("indexList");
  214. QTest::addColumn<IntList>("commandList");
  215. {
  216. QModelIndexList index;
  217. IntList command;
  218. index << model->index(0, 0, QModelIndex());
  219. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  220. index << model->index(1, 0, QModelIndex());
  221. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  222. QTest::newRow("(0, 0) and (1, 0): Select|Rows")
  223. << index
  224. << command;
  225. }
  226. {
  227. QModelIndexList index;
  228. IntList command;
  229. index << model->index(0, 0, QModelIndex());
  230. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  231. index << model->index(0, 1, QModelIndex());
  232. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  233. QTest::newRow("(0, 0) and (1, 0): Select|Columns")
  234. << index
  235. << command;
  236. }
  237. {
  238. QModelIndexList index;
  239. IntList command;
  240. index << model->index(0, 0, QModelIndex());
  241. command << QItemSelectionModel::Select;
  242. index << model->index(1, 1, QModelIndex());
  243. command << QItemSelectionModel::Select;
  244. index << model->index(2, 2, QModelIndex());
  245. command << QItemSelectionModel::SelectCurrent;
  246. QTest::newRow("(0, 0), (1, 1) and (2, 2): Select, Select, SelectCurrent")
  247. << index
  248. << command;
  249. }
  250. {
  251. QModelIndexList index;
  252. IntList command;
  253. index << model->index(0, 0, QModelIndex());
  254. command << QItemSelectionModel::Select;
  255. index << model->index(1, 1, QModelIndex());
  256. command << QItemSelectionModel::Select;
  257. index << model->index(1, 1, QModelIndex());
  258. command << QItemSelectionModel::Toggle;
  259. QTest::newRow("(0, 0), (1, 1) and (1, 1): Select, Select, Toggle")
  260. << index
  261. << command;
  262. }
  263. {
  264. QModelIndexList index;
  265. IntList command;
  266. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  267. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  268. QTest::newRow("child (0, 0) of (0, 0): Select|Rows")
  269. << index
  270. << command;
  271. }
  272. }
  273. void tst_QItemSelectionModel::clear()
  274. {
  275. QFETCH(QModelIndexList, indexList);
  276. QFETCH(IntList, commandList);
  277. // do selections
  278. for (int i=0; i<indexList.count(); ++i) {
  279. selection->select(indexList.at(i), (QItemSelectionModel::SelectionFlags)commandList.at(i));
  280. }
  281. // test that we have selected items
  282. QVERIFY(!selection->selectedIndexes().isEmpty());
  283. selection->clear();
  284. // test that they were all cleared
  285. QVERIFY(selection->selectedIndexes().isEmpty());
  286. }
  287. void tst_QItemSelectionModel::clearAndSelect()
  288. {
  289. // populate selectionmodel
  290. selection->select(model->index(1, 1, QModelIndex()), QItemSelectionModel::Select);
  291. QCOMPARE(selection->selectedIndexes().count(), 1);
  292. QVERIFY(selection->hasSelection());
  293. // ClearAndSelect with empty selection
  294. QItemSelection emptySelection;
  295. selection->select(emptySelection, QItemSelectionModel::ClearAndSelect);
  296. // verify the selectionmodel is empty
  297. QVERIFY(selection->selectedIndexes().isEmpty());
  298. QVERIFY(selection->hasSelection()==false);
  299. }
  300. void tst_QItemSelectionModel::toggleSelection()
  301. {
  302. //test the toggle selection and checks whether selectedIndex
  303. //and hasSelection returns the correct value
  304. selection->clearSelection();
  305. QCOMPARE(selection->selectedIndexes().count(), 0);
  306. QVERIFY(selection->hasSelection()==false);
  307. QModelIndex index=model->index(1, 1, QModelIndex());
  308. // populate selectionmodel
  309. selection->select(index, QItemSelectionModel::Toggle);
  310. QCOMPARE(selection->selectedIndexes().count(), 1);
  311. QVERIFY(selection->hasSelection()==true);
  312. selection->select(index, QItemSelectionModel::Toggle);
  313. QCOMPARE(selection->selectedIndexes().count(), 0);
  314. QVERIFY(selection->hasSelection()==false);
  315. // populate selectionmodel with rows
  316. selection->select(index, QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
  317. QCOMPARE(selection->selectedIndexes().count(), model->columnCount());
  318. QVERIFY(selection->hasSelection()==true);
  319. selection->select(index, QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
  320. QCOMPARE(selection->selectedIndexes().count(), 0);
  321. QVERIFY(selection->hasSelection()==false);
  322. }
  323. void tst_QItemSelectionModel::select_data()
  324. {
  325. QTest::addColumn<QModelIndexList>("indexList");
  326. QTest::addColumn<bool>("useRanges");
  327. QTest::addColumn<IntList>("commandList");
  328. QTest::addColumn<QModelIndexList>("expectedList");
  329. {
  330. QModelIndexList index;
  331. QModelIndexList expected;
  332. IntList command;
  333. index << model->index(0, 0, QModelIndex());
  334. command << QItemSelectionModel::Select;
  335. expected << model->index(0, 0, QModelIndex());
  336. QTest::newRow("(0, 0): Select")
  337. << index
  338. << false
  339. << command
  340. << expected;
  341. }
  342. {
  343. QModelIndexList index;
  344. QModelIndexList expected;
  345. IntList command;
  346. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  347. command << QItemSelectionModel::Select;
  348. expected << model->index(0, 0, model->index(0, 0, QModelIndex()));
  349. QTest::newRow("child (0, 0) of (0, 0): Select")
  350. << index
  351. << false
  352. << command
  353. << expected;
  354. }
  355. {
  356. QModelIndexList index;
  357. QModelIndexList expected;
  358. IntList command;
  359. index << model->index(0, 0, QModelIndex());
  360. command << QItemSelectionModel::Deselect;
  361. QTest::newRow("(0, 0): Deselect")
  362. << index
  363. << false
  364. << command
  365. << expected;
  366. }
  367. {
  368. QModelIndexList index;
  369. QModelIndexList expected;
  370. IntList command;
  371. index << model->index(0, 0, QModelIndex());
  372. command << QItemSelectionModel::Toggle;
  373. expected << model->index(0, 0, QModelIndex());
  374. QTest::newRow("(0, 0): Toggle")
  375. << index
  376. << false
  377. << command
  378. << expected;
  379. }
  380. {
  381. QModelIndexList index;
  382. QModelIndexList expected;
  383. IntList command;
  384. index << model->index(0, 0, QModelIndex());
  385. command << QItemSelectionModel::Select;
  386. index << model->index(0, 0, QModelIndex());
  387. command << QItemSelectionModel::Toggle;
  388. QTest::newRow("(0, 0) and (0, 0): Select and Toggle")
  389. << index
  390. << false
  391. << command
  392. << expected;
  393. }
  394. {
  395. QModelIndexList index;
  396. QModelIndexList expected;
  397. IntList command;
  398. index << model->index(0, 0, QModelIndex());
  399. command << QItemSelectionModel::Select;
  400. index << model->index(0, 0, QModelIndex());
  401. command << QItemSelectionModel::Deselect;
  402. QTest::newRow("(0, 0) and (0, 0): Select and Deselect")
  403. << index
  404. << false
  405. << command
  406. << expected;
  407. }
  408. {
  409. QModelIndexList index;
  410. QModelIndexList expected;
  411. IntList command;
  412. index << model->index(0, 0, QModelIndex());
  413. command << QItemSelectionModel::Select;
  414. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  415. command << QItemSelectionModel::ClearAndSelect;
  416. expected << model->index(0, 0, model->index(0, 0, QModelIndex()));
  417. QTest::newRow("(0, 0) and child (0, 0) of (0, 0): Select and ClearAndSelect")
  418. << index
  419. << false
  420. << command
  421. << expected;
  422. }
  423. {
  424. QModelIndexList index;
  425. QModelIndexList expected;
  426. IntList command;
  427. index << model->index(0, 0, QModelIndex());
  428. index << model->index(4, 0, QModelIndex());
  429. command << QItemSelectionModel::Select;
  430. index << model->index(0, 1, QModelIndex());
  431. index << model->index(4, 1, QModelIndex());
  432. command << QItemSelectionModel::Select;
  433. index << model->index(0, 0, QModelIndex());
  434. index << model->index(4, 1, QModelIndex());
  435. command << QItemSelectionModel::Deselect;
  436. QTest::newRow("(0, 0 to 4, 0) and (0, 1 to 4, 1) and (0, 0 to 4, 1): Select and Select and Deselect")
  437. << index
  438. << true
  439. << command
  440. << expected;
  441. }
  442. {
  443. QModelIndexList index;
  444. QModelIndexList expected;
  445. IntList command;
  446. index << model->index(0, 0, QModelIndex());
  447. command << QItemSelectionModel::Select;
  448. index << model->index(4, 4, QModelIndex());
  449. command << QItemSelectionModel::Select;
  450. expected << model->index(0, 0, QModelIndex()) << model->index(4, 4, QModelIndex());
  451. QTest::newRow("(0, 0) and (4, 4): Select")
  452. << index
  453. << false
  454. << command
  455. << expected;
  456. }
  457. {
  458. QModelIndexList index;
  459. QModelIndexList expected;
  460. IntList command;
  461. index << model->index(0, 0, QModelIndex());
  462. command << QItemSelectionModel::Select;
  463. index << model->index(4, 4, QModelIndex());
  464. command << QItemSelectionModel::ClearAndSelect;
  465. expected << model->index(4, 4, QModelIndex());
  466. QTest::newRow("(0, 0) and (4, 4): Select and ClearAndSelect")
  467. << index
  468. << false
  469. << command
  470. << expected;
  471. }
  472. {
  473. QModelIndexList index;
  474. QModelIndexList expected;
  475. IntList command;
  476. index << model->index(0, 0, QModelIndex());
  477. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  478. index << model->index(4, 4, QModelIndex());
  479. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  480. expected << model->index(0, 0, QModelIndex())
  481. << model->index(0, 1, QModelIndex())
  482. << model->index(0, 2, QModelIndex())
  483. << model->index(0, 3, QModelIndex())
  484. << model->index(0, 4, QModelIndex())
  485. << model->index(4, 0, QModelIndex())
  486. << model->index(4, 1, QModelIndex())
  487. << model->index(4, 2, QModelIndex())
  488. << model->index(4, 3, QModelIndex())
  489. << model->index(4, 4, QModelIndex());
  490. QTest::newRow("(0, 0) and (4, 4): Select|Rows")
  491. << index
  492. << false
  493. << command
  494. << expected;
  495. }
  496. {
  497. QModelIndexList index;
  498. QModelIndexList expected;
  499. IntList command;
  500. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  501. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  502. index << model->index(4, 4, model->index(0, 0, QModelIndex()));
  503. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  504. QModelIndex parent = model->index(0, 0, QModelIndex());
  505. expected << model->index(0, 0, parent)
  506. << model->index(0, 1, parent)
  507. << model->index(0, 2, parent)
  508. << model->index(0, 3, parent)
  509. << model->index(0, 4, parent)
  510. << model->index(4, 0, parent)
  511. << model->index(4, 1, parent)
  512. << model->index(4, 2, parent)
  513. << model->index(4, 3, parent)
  514. << model->index(4, 4, parent);
  515. QTest::newRow("child (0, 0) and (4, 4) of (0, 0): Select|Rows")
  516. << index
  517. << false
  518. << command
  519. << expected;
  520. }
  521. {
  522. QModelIndexList index;
  523. QModelIndexList expected;
  524. IntList command;
  525. index << model->index(0, 0, QModelIndex());
  526. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  527. index << model->index(4, 4, QModelIndex());
  528. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  529. expected << model->index(0, 0, QModelIndex())
  530. << model->index(1, 0, QModelIndex())
  531. << model->index(2, 0, QModelIndex())
  532. << model->index(3, 0, QModelIndex())
  533. << model->index(4, 0, QModelIndex())
  534. << model->index(0, 4, QModelIndex())
  535. << model->index(1, 4, QModelIndex())
  536. << model->index(2, 4, QModelIndex())
  537. << model->index(3, 4, QModelIndex())
  538. << model->index(4, 4, QModelIndex());
  539. QTest::newRow("(0, 0) and (4, 4): Select|Columns")
  540. << index
  541. << false
  542. << command
  543. << expected;
  544. }
  545. {
  546. QModelIndexList index;
  547. QModelIndexList expected;
  548. IntList command;
  549. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  550. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  551. index << model->index(4, 4, model->index(0, 0, QModelIndex()));
  552. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  553. expected << model->index(0, 0, model->index(0, 0, QModelIndex()))
  554. << model->index(1, 0, model->index(0, 0, QModelIndex()))
  555. << model->index(2, 0, model->index(0, 0, QModelIndex()))
  556. << model->index(3, 0, model->index(0, 0, QModelIndex()))
  557. << model->index(4, 0, model->index(0, 0, QModelIndex()))
  558. << model->index(0, 4, model->index(0, 0, QModelIndex()))
  559. << model->index(1, 4, model->index(0, 0, QModelIndex()))
  560. << model->index(2, 4, model->index(0, 0, QModelIndex()))
  561. << model->index(3, 4, model->index(0, 0, QModelIndex()))
  562. << model->index(4, 4, model->index(0, 0, QModelIndex()));
  563. QTest::newRow("child (0, 0) and (4, 4) of (0, 0): Select|Columns")
  564. << index
  565. << false
  566. << command
  567. << expected;
  568. }
  569. {
  570. QModelIndexList index;
  571. QModelIndexList expected;
  572. IntList command;
  573. index << model->index(0, 0, QModelIndex());
  574. index << model->index(4, 0, QModelIndex());
  575. command << QItemSelectionModel::Select;
  576. expected << model->index(0, 0, QModelIndex())
  577. << model->index(1, 0, QModelIndex())
  578. << model->index(2, 0, QModelIndex())
  579. << model->index(3, 0, QModelIndex())
  580. << model->index(4, 0, QModelIndex());
  581. QTest::newRow("(0, 0 to 4, 0): Select")
  582. << index
  583. << true
  584. << command
  585. << expected;
  586. }
  587. /* ### FAILS
  588. {
  589. QModelIndexList index;
  590. QModelIndexList expected;
  591. IntList command;
  592. index << model->index(0, 0, QModelIndex());
  593. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  594. command << QItemSelectionModel::Select;
  595. QTest::newRow("(0, 0 to child 0, 0): Select")
  596. << index
  597. << true
  598. << command
  599. << expected;
  600. }
  601. */
  602. {
  603. QModelIndexList index;
  604. QModelIndexList expected;
  605. IntList command;
  606. index << model->index(0, 0, model->index(0, 0, QModelIndex()));
  607. index << model->index(0, 0, model->index(1, 0, QModelIndex()));
  608. command << QItemSelectionModel::Select;
  609. QTest::newRow("child (0, 0) of (0, 0) to child (0, 0) of (1, 0): Select")
  610. << index
  611. << true
  612. << command
  613. << expected;
  614. }
  615. {
  616. QModelIndexList index;
  617. QModelIndexList expected;
  618. IntList command;
  619. index << model->index(0, 0, QModelIndex());
  620. index << model->index(4, 4, QModelIndex());
  621. command << QItemSelectionModel::Select;
  622. expected << model->index(0, 0, QModelIndex())
  623. << model->index(0, 1, QModelIndex())
  624. << model->index(0, 2, QModelIndex())
  625. << model->index(0, 3, QModelIndex())
  626. << model->index(0, 4, QModelIndex())
  627. << model->index(1, 0, QModelIndex())
  628. << model->index(1, 1, QModelIndex())
  629. << model->index(1, 2, QModelIndex())
  630. << model->index(1, 3, QModelIndex())
  631. << model->index(1, 4, QModelIndex())
  632. << model->index(2, 0, QModelIndex())
  633. << model->index(2, 1, QModelIndex())
  634. << model->index(2, 2, QModelIndex())
  635. << model->index(2, 3, QModelIndex())
  636. << model->index(2, 4, QModelIndex())
  637. << model->index(3, 0, QModelIndex())
  638. << model->index(3, 1, QModelIndex())
  639. << model->index(3, 2, QModelIndex())
  640. << model->index(3, 3, QModelIndex())
  641. << model->index(3, 4, QModelIndex())
  642. << model->index(4, 0, QModelIndex())
  643. << model->index(4, 1, QModelIndex())
  644. << model->index(4, 2, QModelIndex())
  645. << model->index(4, 3, QModelIndex())
  646. << model->index(4, 4, QModelIndex());
  647. QTest::newRow("(0, 0 to 4, 4): Select")
  648. << index
  649. << true
  650. << command
  651. << expected;
  652. }
  653. {
  654. QModelIndexList index;
  655. QModelIndexList expected;
  656. IntList command;
  657. index << model->index(0, 0, QModelIndex());
  658. index << model->index(4, 0, QModelIndex());
  659. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  660. expected << model->index(0, 0, QModelIndex())
  661. << model->index(0, 1, QModelIndex())
  662. << model->index(0, 2, QModelIndex())
  663. << model->index(0, 3, QModelIndex())
  664. << model->index(0, 4, QModelIndex())
  665. << model->index(1, 0, QModelIndex())
  666. << model->index(1, 1, QModelIndex())
  667. << model->index(1, 2, QModelIndex())
  668. << model->index(1, 3, QModelIndex())
  669. << model->index(1, 4, QModelIndex())
  670. << model->index(2, 0, QModelIndex())
  671. << model->index(2, 1, QModelIndex())
  672. << model->index(2, 2, QModelIndex())
  673. << model->index(2, 3, QModelIndex())
  674. << model->index(2, 4, QModelIndex())
  675. << model->index(3, 0, QModelIndex())
  676. << model->index(3, 1, QModelIndex())
  677. << model->index(3, 2, QModelIndex())
  678. << model->index(3, 3, QModelIndex())
  679. << model->index(3, 4, QModelIndex())
  680. << model->index(4, 0, QModelIndex())
  681. << model->index(4, 1, QModelIndex())
  682. << model->index(4, 2, QModelIndex())
  683. << model->index(4, 3, QModelIndex())
  684. << model->index(4, 4, QModelIndex());
  685. QTest::newRow("(0, 0 to 4, 0): Select|Rows")
  686. << index
  687. << true
  688. << command
  689. << expected;
  690. }
  691. {
  692. QModelIndexList index;
  693. QModelIndexList expected;
  694. IntList command;
  695. index << model->index(0, 0, QModelIndex());
  696. index << model->index(0, 4, QModelIndex());
  697. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  698. expected << model->index(0, 0, QModelIndex())
  699. << model->index(0, 1, QModelIndex())
  700. << model->index(0, 2, QModelIndex())
  701. << model->index(0, 3, QModelIndex())
  702. << model->index(0, 4, QModelIndex())
  703. << model->index(1, 0, QModelIndex())
  704. << model->index(1, 1, QModelIndex())
  705. << model->index(1, 2, QModelIndex())
  706. << model->index(1, 3, QModelIndex())
  707. << model->index(1, 4, QModelIndex())
  708. << model->index(2, 0, QModelIndex())
  709. << model->index(2, 1, QModelIndex())
  710. << model->index(2, 2, QModelIndex())
  711. << model->index(2, 3, QModelIndex())
  712. << model->index(2, 4, QModelIndex())
  713. << model->index(3, 0, QModelIndex())
  714. << model->index(3, 1, QModelIndex())
  715. << model->index(3, 2, QModelIndex())
  716. << model->index(3, 3, QModelIndex())
  717. << model->index(3, 4, QModelIndex())
  718. << model->index(4, 0, QModelIndex())
  719. << model->index(4, 1, QModelIndex())
  720. << model->index(4, 2, QModelIndex())
  721. << model->index(4, 3, QModelIndex())
  722. << model->index(4, 4, QModelIndex());
  723. QTest::newRow("(0, 0 to 0, 4): Select|Columns")
  724. << index
  725. << true
  726. << command
  727. << expected;
  728. }
  729. {
  730. QModelIndexList index;
  731. QModelIndexList expected;
  732. IntList command;
  733. index << model->index(0, 0, QModelIndex());
  734. index << model->index(4, 4, QModelIndex());
  735. command << (QItemSelectionModel::Select | QItemSelectionModel::Rows);
  736. expected << model->index(0, 0, QModelIndex())
  737. << model->index(0, 1, QModelIndex())
  738. << model->index(0, 2, QModelIndex())
  739. << model->index(0, 3, QModelIndex())
  740. << model->index(0, 4, QModelIndex())
  741. << model->index(1, 0, QModelIndex())
  742. << model->index(1, 1, QModelIndex())
  743. << model->index(1, 2, QModelIndex())
  744. << model->index(1, 3, QModelIndex())
  745. << model->index(1, 4, QModelIndex())
  746. << model->index(2, 0, QModelIndex())
  747. << model->index(2, 1, QModelIndex())
  748. << model->index(2, 2, QModelIndex())
  749. << model->index(2, 3, QModelIndex())
  750. << model->index(2, 4, QModelIndex())
  751. << model->index(3, 0, QModelIndex())
  752. << model->index(3, 1, QModelIndex())
  753. << model->index(3, 2, QModelIndex())
  754. << model->index(3, 3, QModelIndex())
  755. << model->index(3, 4, QModelIndex())
  756. << model->index(4, 0, QModelIndex())
  757. << model->index(4, 1, QModelIndex())
  758. << model->index(4, 2, QModelIndex())
  759. << model->index(4, 3, QModelIndex())
  760. << model->index(4, 4, QModelIndex());
  761. QTest::newRow("(0, 0 to 4, 4): Select|Rows")
  762. << index
  763. << true
  764. << command
  765. << expected;
  766. }
  767. {
  768. QModelIndexList index;
  769. QModelIndexList expected;
  770. IntList command;
  771. index << model->index(0, 0, QModelIndex());
  772. index << model->index(4, 4, QModelIndex());
  773. command << (QItemSelectionModel::Select | QItemSelectionModel::Columns);
  774. expected << model->index(0, 0, QModelIndex())
  775. << model->index(0, 1, QModelIndex())
  776. << model->index(0, 2, QModelIndex())
  777. << model->index(0, 3, QModelIndex())
  778. << model->index(0, 4, QModelIndex())
  779. << model->index(1, 0, QModelIndex())
  780. << model->index(1, 1, QModelIndex())
  781. << model->index(1, 2, QModelIndex())
  782. << model->index(1, 3, QModelIndex())
  783. << model->index(1, 4, QModelIndex())
  784. << model->index(2, 0, QModelIndex())
  785. << model->index(2, 1, QModelIndex())
  786. << model->index(2, 2, QModelIndex())
  787. << model->index(2, 3, QModelIndex())
  788. << model->index(2, 4, QModelIndex())
  789. << model->index(3, 0, QModelIndex())
  790. << model->index(3, 1, QModelIndex())
  791. << model->index(3, 2, QModelIndex())
  792. << model->index(3, 3, QModelIndex())
  793. << model->index(3, 4, QModelIndex())
  794. << model->index(4, 0, QModelIndex())
  795. << model->index(4, 1, QModelIndex())
  796. << model->index(4, 2, QModelIndex())
  797. << model->index(4, 3, QModelIndex())
  798. << model->index(4, 4, QModelIndex());
  799. QTest::newRow("(0, 0 to 4, 4): Select|Columns")
  800. << index
  801. << true
  802. << command
  803. << expected;
  804. }
  805. {
  806. QModelIndexList index;
  807. QModelIndexList expected;
  808. IntList command;
  809. index << model->index(0, 2, QModelIndex());
  810. index << model->index(4, 2, QModelIndex());
  811. command << QItemSelectionModel::Select;
  812. index << model->index(2, 0, QModelIndex());
  813. index << model->index(2, 4, QModelIndex());
  814. command << QItemSelectionModel::Select;
  815. expected << model->index(0, 2, QModelIndex())
  816. << model->index(1, 2, QModelIndex())
  817. << model->index(2, 2, QModelIndex())
  818. << model->index(3, 2, QModelIndex())
  819. << model->index(4, 2, QModelIndex())
  820. << model->index(2, 0, QModelIndex())
  821. << model->index(2, 1, QModelIndex())
  822. << model->index(2, 3, QModelIndex())
  823. << model->index(2, 4, QModelIndex());
  824. QTest::newRow("(0, 2 to 4, 2) and (2, 0 to 2, 4): Select")
  825. << index
  826. << true
  827. << command
  828. << expected;
  829. }
  830. {
  831. QModelIndexList index;
  832. QModelIndexList expected;
  833. IntList command;
  834. index << model->index(0, 2, QModelIndex());
  835. index << model->index(4, 2, QModelIndex());
  836. command << QItemSelectionModel::Select;
  837. index << model->index(2, 0, QModelIndex());
  838. index << model->index(2, 4, QModelIndex());
  839. command << QItemSelectionModel::SelectCurrent;
  840. expected << model->index(2, 0, QModelIndex())
  841. << model->index(2, 1, QModelIndex())
  842. << model->index(2, 2, QModelIndex())
  843. << model->index(2, 3, QModelIndex())
  844. << model->index(2, 4, QModelIndex());
  845. QTest::newRow("(0, 2 to 4, 2) and (2, 0 to 2, 4): Select and SelectCurrent")
  846. << index
  847. << true
  848. << command
  849. << expected;
  850. }
  851. {
  852. QModelIndexList index;
  853. QModelIndexList expected;
  854. IntList command;
  855. index << model->index(0, 2, QModelIndex());
  856. index << model->index(4, 2, QModelIndex());
  857. command << QItemSelectionModel::Select;
  858. index << model->index(2, 0, QModelIndex());
  859. index << model->index(2, 4, QModelIndex());
  860. command << QItemSelectionModel::Toggle;
  861. expected << model->index(0, 2, QModelIndex())
  862. << model->index(1, 2, QModelIndex())
  863. << model->index(3, 2, QModelIndex())
  864. << model->index(4, 2, QModelIndex())
  865. << model->index(2, 0, QModelIndex())
  866. << model->index(2, 1, QModelIndex())
  867. << model->index(2, 3, QModelIndex())
  868. << model->index(2, 4, QModelIndex());
  869. QTest::newRow("(0, 2 to 4, 2) and (2, 0 to 2, 4): Select and Toggle")
  870. << index
  871. << true
  872. << command
  873. << expected;
  874. }
  875. {
  876. QModelIndexList index;
  877. QModelIndexList expected;
  878. IntList command;
  879. index << model->index(0, 2, QModelIndex());
  880. index << model->index(4, 2, QModelIndex());
  881. command << QItemSelectionModel::Select;
  882. index << model->index(2, 0, QModelIndex());
  883. index << model->index(2, 4, QModelIndex());
  884. command << QItemSelectionModel::Deselect;
  885. expected << model->index(0, 2, QModelIndex())
  886. << model->index(1, 2, QModelIndex())
  887. << model->index(3, 2, QModelIndex())
  888. << model->index(4, 2, QModelIndex());
  889. QTest::newRow("(0, 2 to 4, 2) and (2, 0 to 2, 4): Select and Deselect")
  890. << index
  891. << true
  892. << command
  893. << expected;
  894. }
  895. {
  896. QModelIndexList index;
  897. QModelIndexList expected;
  898. IntList command;
  899. index << model->index(0, 0, QModelIndex());
  900. index << model->index(2, 2, QModelIndex());
  901. command << QItemSelectionModel::Select;
  902. index << model->index(0, 0, QModelIndex());
  903. index << model->index(0, 0, QModelIndex());
  904. command << QItemSelectionModel::Toggle;
  905. expected << model->index(0, 1, QModelIndex())
  906. << model->index(0, 2, QModelIndex())
  907. << model->index(1, 0, QModelIndex())
  908. << model->index(1, 1, QModelIndex())
  909. << model->index(1, 2, QModelIndex())
  910. << model->index(2, 0, QModelIndex())
  911. << model->index(2, 1, QModelIndex())
  912. << model->index(2, 2, QModelIndex());
  913. QTest::newRow("(0, 0 to 2, 2) and (0, 0 to 0, 0): Select and Toggle at selection boundary")
  914. << index
  915. << true
  916. << command
  917. << expected;
  918. }
  919. {
  920. QModelIndexList index;
  921. QModelIndexList expected;
  922. IntList command;
  923. index << model->index(0, 0, QModelIndex());
  924. index << model->index(2, 2, QModelIndex());
  925. command << QItemSelectionModel::Select;
  926. index << model->index(0, 1, QModelIndex());
  927. index << model->index(0, 1, QModelIndex());
  928. command << QItemSelectionModel::Toggle;
  929. expected << model->index(0, 0, QModelIndex())
  930. << model->index(0, 2, QModelIndex())
  931. << model->index(1, 0, QModelIndex())
  932. << model->index(1, 1, QModelIndex())
  933. << model->index(1, 2, QModelIndex())
  934. << model->index(2, 0, QModelIndex())
  935. << model->index(2, 1, QModelIndex())
  936. << model->index(2, 2, QModelIndex());
  937. QTest::newRow("(0, 0 to 2, 2) and (0, 1 to 0, 1): Select and Toggle at selection boundary")
  938. << index
  939. << true
  940. << command
  941. << expected;
  942. }
  943. {
  944. QModelIndexList index;
  945. QModelIndexList expected;
  946. IntList command;
  947. index << model->index(0, 0, QModelIndex());
  948. index << model->index(2, 2, QModelIndex());
  949. command << QItemSelectionModel::Select;
  950. index << model->index(0, 2, QModelIndex());
  951. index << model->index(0, 2, QModelIndex());
  952. command << QItemSelectionModel::Toggle;
  953. expected << model->index(0, 0, QModelIndex())
  954. << model->index(0, 1, QModelIndex())
  955. << model->index(1, 0, QModelIndex())
  956. << model->index(1, 1, QModelIndex())
  957. << model->index(1, 2, QModelIndex())
  958. << model->index(2, 0, QModelIndex())
  959. << model->index(2, 1, QModelIndex())
  960. << model->index(2, 2, QModelIndex());
  961. QTest::newRow("(0, 0 to 2, 2) and (0, 2 to 0, 2): Select and Toggle at selection boundary")
  962. << index
  963. << true
  964. << command
  965. << expected;
  966. }
  967. {
  968. QModelIndexList index;
  969. QModelIndexList expected;
  970. IntList command;
  971. index << model->index(0, 0, QModelIndex());
  972. index << model->index(2, 2, QModelIndex());
  973. command << QItemSelectionModel::Select;
  974. index << model->index(1, 0, QModelIndex());
  975. index << model->index(1, 0, QModelIndex());
  976. command << QItemSelectionModel::Toggle;
  977. expected << model->index(0, 0, QModelIndex())
  978. << model->index(0, 1, QModelIndex())
  979. << model->index(0, 2, QModelIndex())
  980. << model->index(1, 1, QModelIndex())
  981. << model->index(1, 2, QModelIndex())
  982. << model->index(2, 0, QModelIndex())
  983. << model->index(2, 1, QModelIndex())
  984. << model->index(2, 2, QModelIndex());
  985. QTest::newRow("(0, 0 to 2, 2) and (1, 0 to 1, 0): Select and Toggle at selection boundary")
  986. << index
  987. << true
  988. << command
  989. << expected;
  990. }
  991. {
  992. QModelIndexList index;
  993. QModelIndexList expected;
  994. IntList command;
  995. index << model->index(0, 0, QModelIndex());
  996. index << model->index(2, 2, QModelIndex());
  997. command << QItemSelectionModel::Select;
  998. index << model->index(1, 1, QModelIndex());
  999. index << model->index(1, 1, QModelIndex());
  1000. command << QItemSelectionModel::Toggle;
  1001. expected << model->index(0, 0, QModelIndex())
  1002. << model->index(0, 1, QModelIndex())
  1003. << model->index(0, 2, QModelIndex())
  1004. << model->index(1, 0, QModelIndex())
  1005. << model->index(1, 2, QModelIndex())
  1006. << model->index(2, 0, QModelIndex())
  1007. << model->index(2, 1, QModelIndex())
  1008. << model->index(2, 2, QModelIndex());
  1009. QTest::newRow("(0, 0 to 2, 2) and (1, 1 to 1, 1): Select and Toggle at selection boundary")
  1010. << index
  1011. << true
  1012. << command
  1013. << expected;
  1014. }
  1015. {
  1016. QModelIndexList index;
  1017. QModelIndexList expected;
  1018. IntList command;
  1019. index << model->index(0, 0, QModelIndex());
  1020. index << model->index(2, 2, QModelIndex());
  1021. command << QItemSelectionModel::Select;
  1022. index << model->index(1, 2, QModelIndex());
  1023. index << model->index(1, 2, QModelIndex());
  1024. command << QItemSelectionModel::Toggle;
  1025. expected << model->index(0, 0, QModelIndex())
  1026. << model->index(0, 1, QModelIndex())
  1027. << model->index(0, 2, QModelIndex())
  1028. << model->index(1, 0, QModelIndex())
  1029. << model->index(1, 1, QModelIndex())
  1030. << model->index(2, 0, QModelIndex())
  1031. << model->index(2, 1, QModelIndex())
  1032. << model->index(2, 2, QModelIndex());
  1033. QTest::newRow("(0, 0 to 2, 2) and (1, 2 to 1, 2): Select and Toggle at selection boundary")
  1034. << index
  1035. << true
  1036. << command
  1037. << expected;
  1038. }
  1039. {
  1040. QModelIndexList index;
  1041. QModelIndexList expected;
  1042. IntList command;
  1043. index << model->index(0, 0, QModelIndex());
  1044. index << model->index(2, 2, QModelIndex());
  1045. command << QItemSelectionModel::Select;
  1046. index << model->index(2, 0, QModelIndex());
  1047. index << model->index(2, 0, QModelIndex());
  1048. command << QItemSelectionModel::Toggle;
  1049. expected << model->index(0, 0, QModelIndex())
  1050. << model->index(0, 1, QModelIndex())
  1051. << model->index(0, 2, QModelIndex())
  1052. << model->index(1, 0, QModelIndex())
  1053. << model->index(1, 1, QModelIndex())
  1054. << model->index(1, 2, QModelIndex())
  1055. << model->index(2, 1, QModelIndex())
  1056. << model->index(2, 2, QModelIndex());
  1057. QTest::newRow("(0, 0 to 2, 2) and (2, 0 to 2, 0): Select and Toggle at selection boundary")
  1058. << index
  1059. << true
  1060. << command
  1061. << expected;
  1062. }
  1063. {
  1064. QModelIndexList index;
  1065. QModelIndexList expected;
  1066. IntList command;
  1067. index << model->index(0, 0, QModelIndex());
  1068. index << model->index(2, 2, QModelIndex());
  1069. command << QItemSelectionModel::Select;
  1070. index << model->index(2, 1, QModelIndex());
  1071. index << model->index(2, 1, QModelIndex());
  1072. command << QItemSelectionModel::Toggle;
  1073. expected << model->index(0, 0, QModelIndex())
  1074. << model->index(0, 1, QModelIndex())
  1075. << model->index(0, 2, QModelIndex())
  1076. << model->index(1, 0, QModelIndex())
  1077. << model->index(1, 1, QModelIndex())
  1078. << model->index(1, 2, QModelIndex())
  1079. << model->index(2, 0, QModelIndex())
  1080. << model->index(2, 2, QModelIndex());
  1081. QTest::newRow("(0, 0 to 2, 2) and (2, 1 to 2, 1): Select and Toggle at selection boundary")
  1082. << index
  1083. << true
  1084. << command
  1085. << expected;
  1086. }
  1087. {
  1088. QModelIndexList index;
  1089. QModelIndexList expected;
  1090. IntList command;
  1091. index << model->index(0, 0, QModelIndex());
  1092. index << model->index(2, 2, QModelIndex());
  1093. command << QItemSelectionModel::Select;
  1094. index << model->index(2, 2, QModelIndex());
  1095. index << model->index(2, 2, QModelIndex());
  1096. command << QItemSelectionModel::Toggle;
  1097. expected << model->index(0, 0, QModelIndex())
  1098. << model->index(0, 1, QModelIndex())
  1099. << model->index(0, 2, QModelIndex())
  1100. << model->index(1, 0, QModelIndex())
  1101. << model->index(1, 1, QModelIndex())
  1102. << model->index(1, 2, QModelIndex())
  1103. << model->index(2, 0, QModelIndex())
  1104. << model->index(2, 1, QModelIndex());
  1105. QTest::newRow("(0, 0 to 2, 2) and (2, 2 to 2, 2): Select and Toggle at selection boundary")
  1106. << index
  1107. << true
  1108. << command
  1109. << expected;
  1110. }
  1111. {
  1112. QModelIndexList indexes;
  1113. IntList commands;
  1114. QModelIndexList expected;
  1115. indexes << model->index(0, 0, QModelIndex()) << model->index(0, 0, QModelIndex()) // press 0
  1116. << model->index(0, 0, QModelIndex()) << model->index(0, 0, QModelIndex()) // release 0
  1117. << model->index(1, 0, QModelIndex()) << model->index(1, 0, QModelIndex()) // press 1
  1118. << model->index(1, 0, QModelIndex()) << model->index(1, 0, QModelIndex()) // release 1
  1119. << model->index(2, 0, QModelIndex()) << model->index(2, 0, QModelIndex()) // press 2
  1120. << model->index(2, 0, QModelIndex()) << model->index(2, 0, QModelIndex()) // release 2
  1121. << model->index(3, 0, QModelIndex()) << model->index(3, 0, QModelIndex()) // press 3
  1122. << model->index(3, 0, QModelIndex()) << model->index(3, 0, QModelIndex()) // release 3
  1123. << model->index(2, 0, QModelIndex()) << model->index(2, 0, QModelIndex()) // press 2 again
  1124. << model->index(2, 0, QModelIndex()) << model->index(2, 0, QModelIndex());// move 2
  1125. commands << (QItemSelectionModel::NoUpdate) // press 0
  1126. << (QItemSelectionModel::Toggle|QItemSelectionModel::Rows) // release 0
  1127. << (QItemSelectionModel::NoUpdate) // press 1
  1128. << (QItemSelectionModel::Toggle|QItemSelectionModel::Rows) // release 1
  1129. << (QItemSelectionModel::NoUpdate) // press 2
  1130. << (QItemSelectionModel::Toggle|QItemSelectionModel::Rows) // release 2
  1131. << (QItemSelectionModel::NoUpdate) // press 3
  1132. << (QItemSelectionModel::Toggle|QItemSelectionModel::Rows) // release 3
  1133. << (QItemSelectionModel::NoUpdate) // press 2 again
  1134. << (QItemSelectionModel::Toggle/*Current*/|QItemSelectionModel::Rows);// move 2
  1135. expected << model->index(0, 0, QModelIndex())
  1136. << model->index(0, 1, QModelIndex())
  1137. << model->index(0, 2, QModelIndex())
  1138. << model->index(0, 3, QModelIndex())
  1139. << model->index(0, 4, QModelIndex())
  1140. << model->index(1, 0, QModelIndex())
  1141. << model->index(1, 1, QModelIndex())
  1142. << model->index(1, 2, QModelIndex())
  1143. << model->index(1, 3, QModelIndex())
  1144. << model->index(1, 4, QModelIndex())
  1145. /*
  1146. << model->index(2, 0, QModelIndex())
  1147. << model->index(2, 1, QModelIndex())
  1148. << model->index(2, 2, QModelIndex())
  1149. << model->index(2, 3, QModelIndex())
  1150. << model->index(2, 4, QModelIndex())
  1151. */
  1152. << model->index(3, 0, QModelIndex())
  1153. << model->index(3, 1, QModelIndex())
  1154. << model->index(3, 2, QModelIndex())
  1155. << model->index(3, 3, QModelIndex())
  1156. << model->index(3, 4, QModelIndex());
  1157. QTest::newRow("simulated treeview multiselection behavior")
  1158. << indexes
  1159. << true
  1160. << commands
  1161. << expected;
  1162. }
  1163. }
  1164. void tst_QItemSelectionModel::select()
  1165. {
  1166. QFETCH(QModelIndexList, indexList);
  1167. QFETCH(bool, useRanges);
  1168. QFETCH(IntList, commandList);
  1169. QFETCH(QModelIndexList, expectedList);
  1170. int lastCommand = 0;
  1171. // do selections
  1172. for (int i = 0; i<commandList.count(); ++i) {
  1173. if (useRanges) {
  1174. selection->select(QItemSelection(indexList.at(2*i), indexList.at(2*i+1)),
  1175. (QItemSelectionModel::SelectionFlags)commandList.at(i));
  1176. } else {
  1177. selection->select(indexList.at(i),
  1178. (QItemSelectionModel::SelectionFlags)commandList.at(i));
  1179. }
  1180. lastCommand = commandList.at(i);
  1181. }
  1182. QModelIndexList selectedList = selection->selectedIndexes();
  1183. QVERIFY(selection->hasSelection()!=selectedList.isEmpty());
  1184. // debug output
  1185. // for (int i=0; i<selectedList.count(); ++i)
  1186. // qDebug(QString("selected (%1, %2)")
  1187. // .arg(selectedList.at(i).row())
  1188. // .arg(selectedList.at(i).column()));
  1189. // test that the number of indices are as expected
  1190. QVERIFY2(selectedList.count() == expectedList.count(),
  1191. QString("expected indices: %1 actual indices: %2")
  1192. .arg(expectedList.count())
  1193. .arg(selectedList.count()).toLatin1());
  1194. // test existence of each index
  1195. for (int i=0; i<expectedList.count(); ++i) {
  1196. QVERIFY2(selectedList.contains(expectedList.at(i)),
  1197. QString("expected index(%1, %2) not found in selectedIndexes()")
  1198. .arg(expectedList.at(i).row())
  1199. .arg(expectedList.at(i).column()).toLatin1());
  1200. }
  1201. // test that isSelected agrees
  1202. for (int i=0; i<indexList.count(); ++i) {
  1203. QModelIndex idx = indexList.at(i);
  1204. QVERIFY2(selection->isSelected(idx) == selectedList.contains(idx),
  1205. QString("isSelected(index: %1, %2) does not match selectedIndexes()")
  1206. .arg(idx.row())
  1207. .arg(idx.column()).toLatin1());
  1208. }
  1209. //for now we assume Rows/Columns flag is the same for all commands, therefore we just check lastCommand
  1210. // test that isRowSelected agrees
  1211. if (lastCommand & QItemSelectionModel::Rows) {
  1212. for (int i=0; i<selectedList.count(); ++i)
  1213. QVERIFY2(selection->isRowSelected(selectedList.at(i).row(),
  1214. model->parent(selectedList.at(i))),
  1215. QString("isRowSelected(row: %1) does not match selectedIndexes()")
  1216. .arg(selectedList.at(i).row()).toLatin1());
  1217. }
  1218. // test that isColumnSelected agrees
  1219. if (lastCommand & QItemSelectionModel::Columns) {
  1220. for (int i=0; i<selectedList.count(); ++i)
  1221. QVERIFY2(selection->isColumnSelected(selectedList.at(i).column(),
  1222. model->parent(selectedList.at(i))),
  1223. QString("isColumnSelected(column: %1) does not match selectedIndexes()")
  1224. .arg(selectedList.at(i).column()).toLatin1());
  1225. }
  1226. }
  1227. void tst_QItemSelectionModel::persistentselections_data()
  1228. {
  1229. QTest::addColumn<PairList>("indexList");
  1230. QTest::addColumn<IntList>("commandList");
  1231. QTest::addColumn<IntList>("insertRows"); // start, count
  1232. QTest::addColumn<IntList>("insertColumns"); // start, count
  1233. QTest::addColumn<IntList>("deleteRows"); // start, count
  1234. QTest::addColumn<IntList>("deleteColumns"); // start, count
  1235. QTest::addColumn<PairList>("expectedList");
  1236. PairList index, expected;
  1237. IntList command, insertRows, insertColumns, deleteRows, deleteColumns;
  1238. index.clear(); expected.clear(); command.clear();
  1239. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1240. index << IntPair(0, 0);
  1241. command << QItemSelectionModel::ClearAndSelect;
  1242. deleteRows << 4 << 1;
  1243. expected << IntPair(0, 0);
  1244. QTest::newRow("ClearAndSelect (0, 0). Delete last row.")
  1245. << index << command
  1246. << insertRows << insertColumns << deleteRows << deleteColumns
  1247. << expected;
  1248. index.clear(); expected.clear(); command.clear();
  1249. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1250. index << IntPair(0, 0);
  1251. command << QItemSelectionModel::ClearAndSelect;
  1252. deleteRows << 0 << 1;
  1253. QTest::newRow("ClearAndSelect (0, 0). Delete first row.")
  1254. << index << command
  1255. << insertRows << insertColumns << deleteRows << deleteColumns
  1256. << expected;
  1257. index.clear(); expected.clear(); command.clear();
  1258. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1259. index << IntPair(1, 0);
  1260. command << QItemSelectionModel::ClearAndSelect;
  1261. deleteRows << 0 << 1;
  1262. expected << IntPair(0, 0);
  1263. QTest::newRow("ClearAndSelect (1, 0). Delete first row.")
  1264. << index << command
  1265. << insertRows << insertColumns << deleteRows << deleteColumns
  1266. << expected;
  1267. index.clear(); expected.clear(); command.clear();
  1268. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1269. index << IntPair(0, 0);
  1270. command << QItemSelectionModel::ClearAndSelect;
  1271. insertRows << 5 << 1;
  1272. expected << IntPair(0, 0);
  1273. QTest::newRow("ClearAndSelect (0, 0). Append row.")
  1274. << index << command
  1275. << insertRows << insertColumns << deleteRows << deleteColumns
  1276. << expected;
  1277. index.clear(); expected.clear(); command.clear();
  1278. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1279. index << IntPair(0, 0);
  1280. command << QItemSelectionModel::ClearAndSelect;
  1281. insertRows << 0 << 1;
  1282. expected << IntPair(1, 0);
  1283. QTest::newRow("ClearAndSelect (0, 0). Insert before first row.")
  1284. << index << command
  1285. << insertRows << insertColumns << deleteRows << deleteColumns
  1286. << expected;
  1287. index.clear(); expected.clear(); command.clear();
  1288. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1289. index << IntPair(0, 0)
  1290. << IntPair(4, 0);
  1291. command << QItemSelectionModel::ClearAndSelect;
  1292. insertRows << 5 << 1;
  1293. expected << IntPair(0, 0)
  1294. << IntPair(1, 0)
  1295. << IntPair(2, 0)
  1296. << IntPair(3, 0)
  1297. << IntPair(4, 0);
  1298. QTest::newRow("ClearAndSelect (0, 0) to (4, 0). Append row.")
  1299. << index << command
  1300. << insertRows << insertColumns << deleteRows << deleteColumns
  1301. << expected;
  1302. index.clear(); expected.clear(); command.clear();
  1303. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1304. index << IntPair(0, 0)
  1305. << IntPair(4, 0);
  1306. command << QItemSelectionModel::ClearAndSelect;
  1307. insertRows << 0 << 1;
  1308. expected << IntPair(1, 0)
  1309. << IntPair(2, 0)
  1310. << IntPair(3, 0)
  1311. << IntPair(4, 0)
  1312. << IntPair(5, 0);
  1313. QTest::newRow("ClearAndSelect (0, 0) to (4, 0). Insert before first row.")
  1314. << index << command
  1315. << insertRows << insertColumns << deleteRows << deleteColumns
  1316. << expected;
  1317. index.clear(); expected.clear(); command.clear();
  1318. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1319. index << IntPair(0, 0)
  1320. << IntPair(4, 0);
  1321. command << QItemSelectionModel::ClearAndSelect;
  1322. deleteRows << 0 << 1;
  1323. expected << IntPair(0, 0)
  1324. << IntPair(1, 0)
  1325. << IntPair(2, 0)
  1326. << IntPair(3, 0);
  1327. QTest::newRow("ClearAndSelect (0, 0) to (4, 0). Delete first row.")
  1328. << index << command
  1329. << insertRows << insertColumns << deleteRows << deleteColumns
  1330. << expected;
  1331. index.clear(); expected.clear(); command.clear();
  1332. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1333. index << IntPair(0, 0)
  1334. << IntPair(4, 0);
  1335. command << QItemSelectionModel::ClearAndSelect;
  1336. deleteRows << 4 << 1;
  1337. expected << IntPair(0, 0)
  1338. << IntPair(1, 0)
  1339. << IntPair(2, 0)
  1340. << IntPair(3, 0);
  1341. QTest::newRow("ClearAndSelect (0, 0) to (4, 0). Delete last row.")
  1342. << index << command
  1343. << insertRows << insertColumns << deleteRows << deleteColumns
  1344. << expected;
  1345. index.clear(); expected.clear(); command.clear();
  1346. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1347. index << IntPair(0, 0)
  1348. << IntPair(4, 0);
  1349. command << QItemSelectionModel::ClearAndSelect;
  1350. deleteRows << 1 << 3;
  1351. expected << IntPair(0, 0)
  1352. << IntPair(1, 0);
  1353. QTest::newRow("ClearAndSelect (0, 0) to (4, 0). Deleting all but first and last row.")
  1354. << index << command
  1355. << insertRows << insertColumns << deleteRows << deleteColumns
  1356. << expected;
  1357. index.clear(); expected.clear(); command.clear();
  1358. insertRows.clear(); insertColumns.clear(); deleteRows.clear(); deleteColumns.clear();
  1359. index << IntPair(0, 0)
  1360. << IntPair(4, 0);
  1361. command << QItemSelectionModel::ClearAndSelect;
  1362. insertRows << 1 << 1;
  1363. expected << IntPair(0, 0)
  1364. // the inserted row should not be selected
  1365. << IntPair(2, 0)
  1366. << IntPair(3, 0)
  1367. << IntPair(4, 0)
  1368. << IntPair(5, 0);
  1369. QTest::newRow("ClearAndSelect (0, 0) to (4, 0). Insert after first row.")
  1370. << index << command
  1371. << insertRows << insertColumns << deleteRows << deleteColumns
  1372. << expected;
  1373. }
  1374. void tst_QItemSelectionModel::persistentselections()
  1375. {
  1376. QFETCH(PairList, indexList);
  1377. QFETCH(IntList, commandList);
  1378. QFETCH(IntList, insertRows);
  1379. QFETCH(IntList, insertColumns);
  1380. QFETCH(IntList, deleteRows);
  1381. QFETCH(IntList, deleteColumns);
  1382. QFETCH(PairList, expectedList);
  1383. // make sure the model is sane (5x5)
  1384. QCOMPARE(model->rowCount(QModelIndex()), 5);
  1385. QCOMPARE(model->columnCount(QModelIndex()), 5);
  1386. // do selections
  1387. for (int i=0; i<commandList.count(); ++i) {
  1388. if (indexList.count() == commandList.count()) {
  1389. QModelIndex index = model->index(indexList.at(i).first,
  1390. indexList.at(i).second,
  1391. QModelIndex());
  1392. selection->select(index, (QItemSelectionModel::SelectionFlags)commandList.at(i));
  1393. } else {
  1394. QModelIndex tl = model->index(indexList.at(2*i).first,
  1395. indexList.at(2*i).second,
  1396. QModelIndex());
  1397. QModelIndex br = model->index(indexList.at(2*i+1).first,
  1398. indexList.at(2*i+1).second,
  1399. QModelIndex());
  1400. selection->select(QItemSelection(tl, br),
  1401. (QItemSelectionModel::SelectionFlags)commandList.at(i));
  1402. }
  1403. }
  1404. // test that we have selected items
  1405. QVERIFY(!selection->selectedIndexes().isEmpty());
  1406. QVERIFY(selection->hasSelection());
  1407. // insert/delete row and/or columns
  1408. if (insertRows.count() > 1)
  1409. model->insertRows(insertRows.at(0), insertRows.at(1), QModelIndex());
  1410. if (insertColumns.count() > 1)
  1411. model->insertColumns(insertColumns.at(0), insertColumns.at(1), QModelIndex());
  1412. if (deleteRows.count() > 1)
  1413. model->removeRows(deleteRows.at(0), deleteRows.at(1), QModelIndex());
  1414. if (deleteColumns.count() > 1)
  1415. model->removeColumns(deleteColumns.at(0), deleteColumns.at(1), QModelIndex());
  1416. // check that the selected items are the correct number and indexes
  1417. QModelIndexList selectedList = selection->selectedIndexes();
  1418. QCOMPARE(selectedList.count(), expectedList.count());
  1419. foreach(IntPair pair, expectedList) {
  1420. QModelIndex index = model->index(pair.first, pair.second, QModelIndex());
  1421. QVERIFY(selectedList.contains(index));
  1422. }
  1423. }
  1424. // "make reset public"-model
  1425. class MyStandardItemModel: public QStandardItemModel
  1426. {
  1427. Q_OBJECT
  1428. public:
  1429. inline MyStandardItemModel(int i1, int i2): QStandardItemModel(i1, i2) {}
  1430. inline void reset() { QStandardItemModel::reset(); }
  1431. };
  1432. void tst_QItemSelectionModel::resetModel()
  1433. {
  1434. MyStandardItemModel model(20, 20);
  1435. QTreeView view;
  1436. view.setModel(&model);
  1437. QSignalSpy spy(view.selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)));
  1438. view.selectionModel()->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select);
  1439. QCOMPARE(spy.count(), 1);
  1440. model.reset();
  1441. QVERIFY(view.selectionModel()->selection().isEmpty());
  1442. QVERIFY(view.selectionModel()->hasSelection() == false);
  1443. view.selectionModel()->select(QItemSelection(model.index(0, 0), model.index(5, 5)), QItemSelectionModel::Select);
  1444. QCOMPARE(spy.count(), 2);
  1445. QCOMPARE(spy.at(1).count(), 2);
  1446. // make sure we don't get an "old selection"
  1447. QCOMPARE(spy.at(1).at(1).userType(), qMetaTypeId<QItemSelection>());
  1448. QVERIFY(qvariant_cast<QItemSelection>(spy.at(1).at(1)).isEmpty());
  1449. }
  1450. void tst_QItemSelectionModel::removeRows_data()
  1451. {
  1452. QTest::addColumn<int>("rowCount");
  1453. QTest::addColumn<int>("columnCount");
  1454. QTest::addColumn<int>("selectTop");
  1455. QTest::addColumn<int>("selectLeft");
  1456. QTest::addColumn<int>("selectBottom");
  1457. QTest::addColumn<int>("selectRight");
  1458. QTest::addColumn<int>("removeTop");
  1459. QTest::addColumn<int>("removeBottom");
  1460. QTest::addColumn<int>("expectedTop");
  1461. QTest::addColumn<int>("expectedLeft");
  1462. QTest::addColumn<int>("expectedBottom");
  1463. QTest::addColumn<int>("expectedRight");
  1464. QTest::newRow("4x4 <0,1><1,1>")
  1465. << 4 << 4
  1466. << 0 << 1 << 1 << 1
  1467. << 0 << 0
  1468. << 0 << 1 << 0 << 1;
  1469. }
  1470. void tst_QItemSelectionModel::removeRows()
  1471. {
  1472. QFETCH(int, rowCount);
  1473. QFETCH(int, columnCount);
  1474. QFETCH(int, selectTop);
  1475. QFETCH(int, selectLeft);
  1476. QFETCH(int, selectBottom);
  1477. QFETCH(int, selectRight);
  1478. QFETCH(int, removeTop);
  1479. QFETCH(int, removeBottom);
  1480. QFETCH(int, expectedTop);
  1481. QFETCH(int, expectedLeft);
  1482. QFETCH(int, expectedBottom);
  1483. QFETCH(int, expectedRight);
  1484. MyStandardItemModel model(rowCount, columnCount);
  1485. QItemSelectionModel selections(&model);
  1486. QSignalSpy spy(&selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)));
  1487. QModelIndex tl = model.index(selectTop, selectLeft);
  1488. QModelIndex br = model.index(selectBottom, selectRight);
  1489. selections.select(QItemSelection(tl, br), QItemSelectionModel::ClearAndSelect);
  1490. QCOMPARE(spy.count(), 1);
  1491. QVERIFY(selections.isSelected(tl));
  1492. QVERIFY(selections.isSelected(br));
  1493. QVERIFY(selections.hasSelection());
  1494. model.removeRows(removeTop, removeBottom - removeTop + 1);
  1495. QCOMPARE(spy.count(), 2);
  1496. tl = model.index(expectedTop, expectedLeft);
  1497. br = model.index(expectedBottom, expectedRight);
  1498. QVERIFY(selections.isSelected(tl));
  1499. QVERIFY(selections.isSelected(br));
  1500. }
  1501. void tst_QItemSelectionModel::removeColumns_data()
  1502. {
  1503. QTest::addColumn<int>("rowCount");
  1504. QTest::addColumn<int>("columnCount");
  1505. QTest::addColumn<int>("selectTop");
  1506. QTest::addColumn<int>("selectLeft");
  1507. QTest::addColumn<int>("selectBottom");
  1508. QTest::addColumn<int>("selectRight");
  1509. QTest::addColumn<int>("removeLeft");
  1510. QTest::addColumn<int>("removeRight");
  1511. QTest::addColumn<int>("expectedTop");
  1512. QTest::addColumn<int>("expectedLeft");
  1513. QTest::addColumn<int>("expectedBottom");
  1514. QTest::addColumn<int>("expectedRight");
  1515. QTest::newRow("4x4 <0,1><1,1>")
  1516. << 4 << 4
  1517. << 1 << 0 << 1 << 1
  1518. << 0 << 0
  1519. << 1 << 0 << 1 << 0;
  1520. }
  1521. void tst_QItemSelectionModel::removeColumns()
  1522. {
  1523. QFETCH(int, rowCount);
  1524. QFETCH(int, columnCount);
  1525. QFETCH(int, selectTop);
  1526. QFETCH(int, selectLeft);
  1527. QFETCH(int, selectBottom);
  1528. QFETCH(int, selectRight);
  1529. QFETCH(int, removeLeft);
  1530. QFETCH(int, removeRight);
  1531. QFETCH(int, expectedTop);
  1532. QFETCH(int, expectedLeft);
  1533. QFETCH(int, expectedBottom);
  1534. QFETCH(int, expectedRight);
  1535. MyStandardItemModel model(rowCount, columnCount);
  1536. QItemSelectionModel selections(&model);
  1537. QSignalSpy spy(&selections, SIGNAL(selectionChanged(QItemSelection,QItemSelection)));
  1538. QModelIndex tl = model.index(selectTop, selectLeft);
  1539. QModelIndex br = model.index(selectBottom, selectRight);
  1540. selections.select(QItemSelection(tl, br), QItemSelectionModel::ClearAndSelect);
  1541. QCOMPARE(spy.count(), 1);
  1542. QVERIFY(selections.isSelected(tl));
  1543. QVERIFY(selections.isSelected(br));
  1544. QVERIFY(selections.hasSelection());
  1545. model.removeColumns(removeLeft, removeRight - removeLeft + 1);
  1546. QCOMPARE(spy.count(), 2);
  1547. tl = model.index(expectedTop, expectedLeft);
  1548. br = model.index(expectedBottom, expectedRight);
  1549. QVERIFY(selections.isSelected(tl));
  1550. QVERIFY(selections.isSelected(br));
  1551. }
  1552. typedef QList<IntList> IntListList;
  1553. typedef QPair<IntPair, IntPair> IntPairPair;
  1554. typedef QList<IntPairPair> IntPairPairList;
  1555. Q_DECLARE_METATYPE(IntListList)
  1556. Q_DECLARE_METATYPE(IntPairPair)
  1557. Q_DECLARE_METATYPE(IntPairPairList)
  1558. void tst_QItemSelectionModel::modelLayoutChanged_data()
  1559. {
  1560. QTest::addColumn<IntListList>("items");
  1561. QTest::addColumn<IntPairPairList>("initialSelectedRanges");
  1562. QTest::addColumn<int>("sortOrder");
  1563. QTest::addColumn<int>("sortColumn");
  1564. QTest::addColumn<IntPairPairList>("expectedSelectedRanges");
  1565. QTest::newRow("everything selected, then row order reversed")
  1566. << (IntListList()
  1567. << (IntList() << 0 << 1 << 2 << 3)
  1568. << (IntList() << 3 << 2 << 1 << 0))
  1569. << (IntPairPairList()
  1570. << IntPairPair(IntPair(0, 0), IntPair(3, 1)))
  1571. << int(Qt::DescendingOrder)
  1572. << 0
  1573. << (IntPairPairList()
  1574. << IntPairPair(IntPair(0, 0), IntPair(3, 1)));
  1575. QTest::newRow("first two rows selected, then row order reversed")
  1576. << (IntListList()
  1577. << (IntList() << 0 << 1 << 2 << 3)
  1578. << (IntList() << 3 << 2 << 1 << 0))
  1579. << (IntPairPairList()
  1580. << IntPairPair(IntPair(0, 0), IntPair(1, 1)))
  1581. << int(Qt::DescendingOrder)
  1582. << 0
  1583. << (IntPairPairList()
  1584. << IntPairPair(IntPair(2, 0), IntPair(3, 1)));
  1585. QTest::newRow("middle two rows selected, then row order reversed")
  1586. << (IntListList()
  1587. << (IntList() << 0 << 1 << 2 << 3)
  1588. << (IntList() << 3 << 2 << 1 << 0))
  1589. << (IntPairPairList()
  1590. << IntPairPair(IntPair(1, 0), IntPair(2, 1)))
  1591. << int(Qt::DescendingOrder)
  1592. << 0
  1593. << (IntPairPairList()
  1594. << IntPairPair(IntPair(1, 0), IntPair(2, 1)));
  1595. QTest::newRow("two ranges")
  1596. << (IntListList()
  1597. << (IntList() << 2 << 0 << 3 << 1)
  1598. << (IntList() << 2 << 0 << 3 << 1))
  1599. << (IntPairPairList()
  1600. << IntPairPair(IntPair(1, 0), IntPair(1, 1))
  1601. << IntPairPair(IntPair(3, 0), IntPair(3, 1)))
  1602. << int(Qt::AscendingOrder)
  1603. << 0
  1604. << (IntPairPairList()
  1605. << IntPairPair(IntPair(0, 0), IntPair(0, 1))
  1606. << IntPairPair(IntPair(1, 0), IntPair(1, 1)));
  1607. }
  1608. void tst_QItemSelectionModel::modelLayoutChanged()
  1609. {
  1610. QFETCH(IntListList, items);
  1611. QFETCH(IntPairPairList, initialSelectedRanges);
  1612. QFETCH(int, sortOrder);
  1613. QFETCH(int, sortColumn);
  1614. QFETCH(IntPairPairList, expectedSelectedRanges);
  1615. MyStandardItemModel model(items.at(0).count(), items.count());
  1616. // initialize model data
  1617. for (int i = 0; i < model.rowCount(); ++i) {
  1618. for (int j = 0; j < model.columnCount(); ++j) {
  1619. QModelIndex index = model.index(i, j);
  1620. model.setData(index, items.at(j).at(i), Qt::DisplayRole);
  1621. }
  1622. }
  1623. // select initial ranges
  1624. QItemSelectionModel selectionModel(&model);
  1625. foreach (IntPairPair range, initialSelectedRanges) {
  1626. IntPair tl = range.first;
  1627. IntPair br = range.second;
  1628. QItemSelection selection(
  1629. model.index(tl.first, tl.second),
  1630. model.index(br.first, br.second));
  1631. selectionModel.select(selection, QItemSelectionModel::Select);
  1632. }
  1633. // sort the model
  1634. model.sort(sortColumn, Qt::SortOrder(sortOrder));
  1635. // verify that selection is as expected
  1636. QItemSelection selection = selectionModel.selection();
  1637. QCOMPARE(selection.count(), expectedSelectedRanges.count());
  1638. QVERIFY(selectionModel.hasSelection() == !expectedSelectedRanges.isEmpty());
  1639. for (int i = 0; i < expectedSelectedRanges.count(); ++i) {
  1640. IntPairPair expectedRange = expectedSelectedRanges.at(i);
  1641. IntPair expectedTl = expectedRange.first;
  1642. IntPair expectedBr = expectedRange.second;
  1643. QItemSelectionRange actualRange = selection.at(i);
  1644. QModelIndex actualTl = actualRange.topLeft();
  1645. QModelIndex actualBr = actualRange.bottomRight();
  1646. QCOMPARE(actualTl.row(), expectedTl.first);
  1647. QCOMPARE(actualTl.column(), expectedTl.second);
  1648. QCOMPARE(actualBr.row(), expectedBr.first);
  1649. QCOMPARE(actualBr.column(), expectedBr.second);
  1650. }
  1651. }
  1652. void tst_QItemSelectionModel::selectedRows_data()
  1653. {
  1654. QTest::addColumn<int>("rowCount");
  1655. QTest::addColumn<int>("columnCount");
  1656. QTest::addColumn<int>("column");
  1657. QTest::addColumn<IntList>("selectRows");
  1658. QTest::addColumn<IntList>("expectedRows");
  1659. QTest::addColumn<IntList>("unexpectedRows");
  1660. QTest::newRow("10x10, first row")
  1661. << 10 << 10 << 0
  1662. << (IntList() << 0)
  1663. << (IntList() << 0)
  1664. << (IntList() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9);
  1665. QTest::newRow("10x10, first 4 rows")
  1666. << 10 << 10 << 0
  1667. << (IntList() << 0 << 1 << 2 << 3)
  1668. << (IntList() << 0 << 1 << 2 << 3)
  1669. << (IntList() << 4 << 5 << 6 << 7 << 8 << 9);
  1670. QTest::newRow("10x10, last 4 rows")
  1671. << 10 << 10 << 0
  1672. << (IntList() << 6 << 7 << 8 << 9)
  1673. << (IntList() << 6 << 7 << 8 << 9)
  1674. << (IntList() << 0 << 1 << 2 << 3 << 4 << 6);
  1675. }
  1676. void tst_QItemSelectionModel::selectedRows()
  1677. {
  1678. QFETCH(int, rowCount);
  1679. QFETCH(int, columnCount);
  1680. QFETCH(int, column);
  1681. QFETCH(IntList, selectRows);
  1682. QFETCH(IntList, expectedRows);
  1683. QFETCH(IntList, unexpectedRows);
  1684. MyStandardItemModel model(rowCount, columnCount);
  1685. QItemSelectionModel selectionModel(&model);
  1686. for (int i = 0; i < selectRows.count(); ++i)
  1687. selectionModel.select(model.index(selectRows.at(i), 0),
  1688. QItemSelectionModel::Select
  1689. |QItemSelectionModel::Rows);
  1690. for (int j = 0; j < selectRows.count(); ++j)
  1691. QVERIFY(selectionModel.isRowSelected(expectedRows.at(j), QModelIndex()));
  1692. for (int k = 0; k < selectRows.count(); ++k)
  1693. QVERIFY(!selectionModel.isRowSelected(unexpectedRows.at(k), QModelIndex()));
  1694. QModelIndexList selectedRowIndexes = selectionModel.selectedRows(column);
  1695. QCOMPARE(selectedRowIndexes.count(), expectedRows.count());
  1696. qSort(selectedRowIndexes);
  1697. for (int l = 0; l < selectedRowIndexes.count(); ++l) {
  1698. QCOMPARE(selectedRowIndexes.at(l).row(), expectedRows.at(l));
  1699. QCOMPARE(selectedRowIndexes.at(l).column(), column);
  1700. }
  1701. }
  1702. void tst_QItemSelectionModel::selectedColumns_data()
  1703. {
  1704. QTest::addColumn<int>("rowCount");
  1705. QTest::addColumn<int>("columnCount");
  1706. QTest::addColumn<int>("row");
  1707. QTest::addColumn<IntList>("selectColumns");
  1708. QTest::addColumn<IntList>("expectedColumns");
  1709. QTest::addColumn<IntList>("unexpectedColumns");
  1710. QTest::newRow("10x10, first columns")
  1711. << 10 << 10 << 0
  1712. << (IntList() << 0)
  1713. << (IntList() << 0)
  1714. << (IntList() << 1 << 2 << 3 << 4 << 5 << 6 << 7 << 8 << 9);
  1715. QTest::newRow("10x10, first 4 columns")
  1716. << 10 << 10 << 0
  1717. << (IntList() << 0 << 1 << 2 << 3)
  1718. << (IntList() << 0 << 1 << 2 << 3)
  1719. << (IntList() << 4 << 5 << 6 << 7 << 8 << 9);
  1720. QTest::newRow("10x10, last 4 columns")
  1721. << 10 << 10 << 0
  1722. << (IntList() << 6 << 7 << 8 << 9)
  1723. << (IntList() << 6 << 7 << 8 << 9)
  1724. << (IntList() << 0 << 1 << 2 << 3 << 4 << 6);
  1725. }
  1726. void tst_QItemSelectionModel::selectedColumns()
  1727. {
  1728. QFETCH(int, rowCount);
  1729. QFETCH(int, columnCount);
  1730. QFETCH(int, row);
  1731. QFETCH(IntList, selectColumns);
  1732. QFETCH(IntList, expectedColumns);
  1733. QFETCH(IntList, unexpectedColumns);
  1734. MyStandardItemModel model(rowCount, columnCount);
  1735. QItemSelectionModel selectionModel(&model);
  1736. for (int i = 0; i < selectColumns.count(); ++i)
  1737. selectionModel.select(model.index(0, selectColumns.at(i)),
  1738. QItemSelectionModel::Select
  1739. |QItemSelectionModel::Columns);
  1740. for (int j = 0; j < selectColumns.count(); ++j)
  1741. QVERIFY(selectionModel.isColumnSelected(expectedColumns.at(j), QModelIndex()));
  1742. for (int k = 0; k < selectColumns.count(); ++k)
  1743. QVERIFY(!selectionModel.isColumnSelected(unexpectedColumns.at(k), QModelIndex()));
  1744. QModelIndexList selectedColumnIndexes = selectionModel.selectedColumns(row);
  1745. QCOMPARE(selectedColumnIndexes.count(), expectedColumns.count());
  1746. qSort(selectedColumnIndexes);
  1747. for (int l = 0; l < selectedColumnIndexes.count(); ++l) {
  1748. QCOMPARE(selectedColumnIndexes.at(l).column(), expectedColumns.at(l));
  1749. QCOMPARE(selectedColumnIndexes.at(l).row(), row);
  1750. }
  1751. }
  1752. void tst_QItemSelectionModel::setCurrentIndex()
  1753. {
  1754. // Build up a simple tree
  1755. QStandardItemModel *treemodel = new QStandardItemModel(0, 1);
  1756. treemodel->insertRow(0, new QStandardItem(1));
  1757. treemodel->insertRow(1, new QStandardItem(2));
  1758. QTreeView treeView;
  1759. treeView.setModel(treemodel);
  1760. QItemSelectionModel *selectionModel = treeView.selectionModel();
  1761. selectionModel->setCurrentIndex(
  1762. treemodel->index(0, 0, treemodel->index(0, 0)),
  1763. QItemSelectionModel::SelectCurrent);
  1764. QSignalSpy currentSpy(selectionModel,
  1765. SIGNAL(currentChanged(QModelIndex,QModelIndex)));
  1766. QSignalSpy rowSpy(selectionModel,
  1767. SIGNAL(currentRowChanged(QModelIndex,QModelIndex)));
  1768. QSignalSpy columnSpy(selectionModel,
  1769. SIGNAL(currentColumnChanged(QModelIndex,QModelIndex)));
  1770. // Select the same row and column indexes, but with a different parent
  1771. selectionModel->setCurrentIndex(
  1772. treemodel->index(0, 0, treemodel->index(1, 0)),
  1773. QItemSelectionModel::SelectCurrent);
  1774. QCOMPARE(currentSpy.count(), 1);
  1775. QCOMPARE(rowSpy.count(), 1);
  1776. QCOMPARE(columnSpy.count(), 1);
  1777. // Select another row in the same parent
  1778. selectionModel->setCurrentIndex(
  1779. treemodel->index(1, 0, treemodel->index(1, 0)),
  1780. QItemSelectionModel::SelectCurrent);
  1781. QCOMPARE(currentSpy.count(), 2);
  1782. QCOMPARE(rowSpy.count(), 2);
  1783. QCOMPARE(columnSpy.count(), 1);
  1784. delete treemodel;
  1785. }
  1786. void tst_QItemSelectionModel::splitOnInsert()
  1787. {
  1788. QStandardItemModel model(4, 1);
  1789. QItemSelectionModel selectionModel(&model);
  1790. selectionModel.select(model.index(2, 0), QItemSelectionModel::Select);
  1791. model.insertRow(2);
  1792. model.removeRow(3);
  1793. QVERIFY(!selectionModel.isSelected(model.index(1, 0)));
  1794. }
  1795. void tst_QItemSelectionModel::task196285_rowIntersectsSelection()
  1796. {
  1797. QTableWidget table;
  1798. table.setColumnCount(1);
  1799. table.setRowCount(1);
  1800. table.setItem(0, 0, new QTableWidgetItem("foo"));
  1801. QAbstractItemModel *model = table.model();
  1802. QItemSelectionModel *selectionModel = table.selectionModel();
  1803. QModelIndex index = model->index(0, 0, QModelIndex());
  1804. selectionModel->select(index, QItemSelectionModel::Select);
  1805. QVERIFY(selectionModel->rowIntersectsSelection(0, QModelIndex()));
  1806. QVERIFY(selectionModel->columnIntersectsSelection(0, QModelIndex()));
  1807. selectionModel->select(index, QItemSelectionModel::Deselect);
  1808. QVERIFY(!selectionModel->rowIntersectsSelection(0, QModelIndex()));
  1809. QVERIFY(!selectionModel->columnIntersectsSelection(0, QModelIndex()));
  1810. selectionModel->select(index, QItemSelectionModel::Toggle);
  1811. QVERIFY(selectionModel->rowIntersectsSelection(0, QModelIndex()));
  1812. QVERIFY(selectionModel->columnIntersectsSelection(0, QModelIndex()));
  1813. selectionModel->select(index, QItemSelectionModel::Toggle);
  1814. QVERIFY(!selectionModel->rowIntersectsSelection(0, QModelIndex()));
  1815. QVERIFY(!selectionModel->columnIntersectsSelection(0, QModelIndex()));
  1816. }
  1817. void tst_QItemSelectionModel::unselectable()
  1818. {
  1819. QTreeWidget w;
  1820. for (int i = 0; i < 10; ++i)
  1821. w.setItemSelected(new QTreeWidgetItem(&w), true);
  1822. QCOMPARE(w.topLevelItemCount(), 10);
  1823. QCOMPARE(w.selectionModel()->selectedIndexes().count(), 10);
  1824. QCOMPARE(w.selectionModel()->selectedRows().count(), 10);
  1825. for (int j = 0; j < 10; ++j)
  1826. w.topLevelItem(j)->setFlags(0);
  1827. QCOMPARE(w.selectionModel()->selectedIndexes().count(), 0);
  1828. QCOMPARE(w.selectionModel()->selectedRows().count(), 0);
  1829. }
  1830. void tst_QItemSelectionModel::task220420_selectedIndexes()
  1831. {
  1832. QStandardItemModel model(2, 2);
  1833. QItemSelectionModel selectionModel(&model);
  1834. QItemSelection selection;
  1835. selection.append(QItemSelectionRange(model.index(0,0)));
  1836. selection.append(QItemSelectionRange(model.index(0,1)));
  1837. //we select the 1st row
  1838. selectionModel.select(selection, QItemSelectionModel::Rows | QItemSelectionModel::Select);
  1839. QCOMPARE(selectionModel.selectedRows().count(), 1);
  1840. QCOMPARE(selectionModel.selectedIndexes().count(), model.columnCount());
  1841. }
  1842. class QtTestTableModel: public QAbstractTableModel
  1843. {
  1844. Q_OBJECT
  1845. public:
  1846. QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = 0)
  1847. : QAbstractTableModel(parent),
  1848. row_count(rows),
  1849. column_count(columns) {}
  1850. int rowCount(const QModelIndex& = QModelIndex()) const { return row_count; }
  1851. int columnCount(const QModelIndex& = QModelIndex()) const { return column_count; }
  1852. bool isEditable(const QModelIndex &) const { return true; }
  1853. QVariant data(const QModelIndex &idx, int role) const
  1854. {
  1855. if (role == Qt::DisplayRole || role == Qt::EditRole)
  1856. return QString("[%1,%2]").arg(idx.row()).arg(idx.column());
  1857. return QVariant();
  1858. }
  1859. int row_count;
  1860. int column_count;
  1861. friend class tst_QItemSelectionModel;
  1862. };
  1863. void tst_QItemSelectionModel::task240734_layoutChanged()
  1864. {
  1865. QtTestTableModel model(1,1);
  1866. QItemSelectionModel selectionModel(&model);
  1867. selectionModel.select(model.index(0,0), QItemSelectionModel::Select);
  1868. QCOMPARE(selectionModel.selectedIndexes().count() , 1);
  1869. emit model.layoutAboutToBeChanged();
  1870. model.row_count = 5;
  1871. emit model.layoutChanged();
  1872. //The selection should not change.
  1873. QCOMPARE(selectionModel.selectedIndexes().count() , 1);
  1874. QCOMPARE(selectionModel.selectedIndexes().first() , model.index(0,0));
  1875. }
  1876. void tst_QItemSelectionModel::merge_data()
  1877. {
  1878. QTest::addColumn<QItemSelection>("init");
  1879. QTest::addColumn<QItemSelection>("other");
  1880. QTest::addColumn<int>("command");
  1881. QTest::addColumn<QItemSelection>("result");
  1882. QTest::newRow("Simple select")
  1883. << QItemSelection()
  1884. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1885. << int(QItemSelectionModel::Select)
  1886. << QItemSelection(model->index(2, 1) , model->index(3, 4));
  1887. QTest::newRow("Simple deselect")
  1888. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1889. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1890. << int(QItemSelectionModel::Deselect)
  1891. << QItemSelection();
  1892. QTest::newRow("Simple Toggle deselect")
  1893. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1894. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1895. << int(QItemSelectionModel::Toggle)
  1896. << QItemSelection();
  1897. QTest::newRow("Simple Toggle select")
  1898. << QItemSelection()
  1899. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1900. << int(QItemSelectionModel::Toggle)
  1901. << QItemSelection(model->index(2, 1) , model->index(3, 4));
  1902. QTest::newRow("Add select")
  1903. << QItemSelection(model->index(2, 1) , model->index(3, 3))
  1904. << QItemSelection(model->index(2, 2) , model->index(3, 4))
  1905. << int(QItemSelectionModel::Select)
  1906. << QItemSelection(model->index(2, 1) , model->index(3, 4));
  1907. QTest::newRow("Deselect")
  1908. << QItemSelection(model->index(2, 1) , model->index(3, 4))
  1909. << QItemSelection(model->index(2, 2) , model->index(3, 4))
  1910. << int(QItemSelectionModel::Deselect)
  1911. << QItemSelection(model->index(2, 1) , model->index(3, 1));
  1912. QItemSelection r1(model->index(2, 1) , model->index(3, 1));
  1913. r1.select(model->index(2, 4) , model->index(3, 4));
  1914. QTest::newRow("Toggle")
  1915. << QItemSelection(model->index(2, 1) , model->index(3, 3))
  1916. << QItemSelection(model->index(2, 2) , model->index(3, 4))
  1917. << int(QItemSelectionModel::Toggle)
  1918. << r1;
  1919. }
  1920. void tst_QItemSelectionModel::merge()
  1921. {
  1922. QFETCH(QItemSelection, init);
  1923. QFETCH(QItemSelection, other);
  1924. QFETCH(int, command);
  1925. QFETCH(QItemSelection, result);
  1926. init.merge(other, QItemSelectionModel::SelectionFlags(command));
  1927. foreach(const QModelIndex &idx, init.indexes())
  1928. QVERIFY(result.contains(idx));
  1929. foreach(const QModelIndex &idx, result.indexes())
  1930. QVERIFY(init.contains(idx));
  1931. }
  1932. void tst_QItemSelectionModel::task119433_isRowSelected()
  1933. {
  1934. QStandardItemModel model(2,2);
  1935. model.setData(model.index(0,0), 0, Qt::UserRole - 1);
  1936. QItemSelectionModel sel(&model);
  1937. sel.select( QItemSelection(model.index(0,0), model.index(0, 1)), QItemSelectionModel::Select);
  1938. QCOMPARE(sel.selectedIndexes().count(), 1);
  1939. QVERIFY(sel.isRowSelected(0, QModelIndex()));
  1940. }
  1941. void tst_QItemSelectionModel::task252069_rowIntersectsSelection()
  1942. {
  1943. QStandardItemModel m;
  1944. for (int i=0; i<8; ++i) {
  1945. for (int j=0; j<8; ++j) {
  1946. QStandardItem *item = new QStandardItem(QString("Item number %1").arg(i));
  1947. if ((i % 2 == 0 && j == 0) ||
  1948. (j % 2 == 0 && i == 0) ||
  1949. j == 5 || i == 5 ) {
  1950. item->setEnabled(false);
  1951. //item->setSelectable(false);
  1952. }
  1953. m.setItem(i, j, item);
  1954. }
  1955. }
  1956. QItemSelectionModel selected(&m);
  1957. //nothing is selected
  1958. QVERIFY(!selected.rowIntersectsSelection(0, QModelIndex()));
  1959. QVERIFY(!selected.rowIntersectsSelection(2, QModelIndex()));
  1960. QVERIFY(!selected.rowIntersectsSelection(3, QModelIndex()));
  1961. QVERIFY(!selected.rowIntersectsSelection(5, QModelIndex()));
  1962. QVERIFY(!selected.columnIntersectsSelection(0, QModelIndex()));
  1963. QVERIFY(!selected.columnIntersectsSelection(2, QModelIndex()));
  1964. QVERIFY(!selected.columnIntersectsSelection(3, QModelIndex()));
  1965. QVERIFY(!selected.columnIntersectsSelection(5, QModelIndex()));
  1966. selected.select(m.index(2, 0), QItemSelectionModel::Select | QItemSelectionModel::Rows);
  1967. QVERIFY(!selected.rowIntersectsSelection(0, QModelIndex()));
  1968. QVERIFY( selected.rowIntersectsSelection(2, QModelIndex()));
  1969. QVERIFY(!selected.rowIntersectsSelection(3, QModelIndex()));
  1970. QVERIFY(!selected.rowIntersectsSelection(5, QModelIndex()));
  1971. QVERIFY(!selected.columnIntersectsSelection(0, QModelIndex()));
  1972. QVERIFY( selected.columnIntersectsSelection(2, QModelIndex()));
  1973. QVERIFY( selected.columnIntersectsSelection(3, QModelIndex()));
  1974. QVERIFY(!selected.columnIntersectsSelection(5, QModelIndex()));
  1975. selected.select(m.index(0, 5), QItemSelectionModel::Select | QItemSelectionModel::Columns);
  1976. QVERIFY(!selected.rowIntersectsSelection(0, QModelIndex()));
  1977. QVERIFY( selected.rowIntersectsSelection(2, QModelIndex()));
  1978. QVERIFY(!selected.rowIntersectsSelection(3, QModelIndex()));
  1979. QVERIFY(!selected.rowIntersectsSelection(5, QModelIndex()));
  1980. QVERIFY(!selected.columnIntersectsSelection(0, QModelIndex()));
  1981. QVERIFY( selected.columnIntersectsSelection(2, QModelIndex()));
  1982. QVERIFY( selected.columnIntersectsSelection(3, QModelIndex()));
  1983. QVERIFY(!selected.columnIntersectsSelection(5, QModelIndex()));
  1984. }
  1985. void tst_QItemSelectionModel::task232634_childrenDeselectionSignal()
  1986. {
  1987. QStandardItemModel model;
  1988. QStandardItem *parentItem = model.invisibleRootItem();
  1989. for (int i = 0; i < 4; ++i) {
  1990. QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
  1991. parentItem->appendRow(item);
  1992. parentItem = item;
  1993. }
  1994. QModelIndex root = model.index(0,0);
  1995. QModelIndex par = root.child(0,0);
  1996. QModelIndex sel = par.child(0,0);
  1997. QItemSelectionModel selectionModel(&model);
  1998. selectionModel.select(sel, QItemSelectionModel::SelectCurrent);
  1999. QSignalSpy deselectSpy(&selectionModel, SIGNAL(selectionChanged(const QItemSelection& , const QItemSelection&)));
  2000. model.removeRows(0, 1, root);
  2001. QVERIFY(deselectSpy.count() == 1);
  2002. // More testing stress for the patch.
  2003. model.clear();
  2004. selectionModel.clear();
  2005. parentItem = model.invisibleRootItem();
  2006. for (int i = 0; i < 2; ++i) {
  2007. QStandardItem *item = new QStandardItem(QString("item %0").arg(i));
  2008. parentItem->appendRow(item);
  2009. }
  2010. for (int i = 0; i < 2; ++i) {
  2011. parentItem = model.invisibleRootItem()->child(i, 0);
  2012. for (int j = 0; j < 2; ++j) {
  2013. QStandardItem *item = new QStandardItem(QString("item %0.%1").arg(i).arg(j));
  2014. parentItem->appendRow(item);
  2015. }
  2016. }
  2017. sel = model.index(0, 0).child(0, 0);
  2018. selectionModel.select(sel, QItemSelectionModel::Select);
  2019. QModelIndex sel2 = model.index(1, 0).child(0, 0);
  2020. selectionModel.select(sel2, QItemSelectionModel::Select);
  2021. QVERIFY(selectionModel.selection().contains(sel));
  2022. QVERIFY(selectionModel.selection().contains(sel2));
  2023. deselectSpy.clear();
  2024. model.removeRow(0, model.index(0, 0));
  2025. QVERIFY(deselectSpy.count() == 1);
  2026. QVERIFY(!selectionModel.selection().contains(sel));
  2027. QVERIFY(selectionModel.selection().contains(sel2));
  2028. }
  2029. void tst_QItemSelectionModel::task260134_layoutChangedWithAllSelected()
  2030. {
  2031. QStringListModel model( QStringList() << "foo" << "bar" << "foo2");
  2032. QSortFilterProxyModel proxy;
  2033. proxy.setSourceModel(&model);
  2034. QItemSelectionModel selection(&proxy);
  2035. QCOMPARE(model.rowCount(), 3);
  2036. QCOMPARE(proxy.rowCount(), 3);
  2037. proxy.setFilterRegExp( QRegExp("f"));
  2038. QCOMPARE(proxy.rowCount(), 2);
  2039. QList<QPersistentModelIndex> indexList;
  2040. indexList << proxy.index(0,0) << proxy.index(1,0);
  2041. selection.select( QItemSelection(indexList.first(), indexList.last()), QItemSelectionModel::Select);
  2042. //let's check the selection hasn't changed
  2043. QCOMPARE(selection.selectedIndexes().count(), indexList.count());
  2044. foreach(QPersistentModelIndex index, indexList)
  2045. QVERIFY(selection.isSelected(index));
  2046. proxy.setFilterRegExp(QRegExp());
  2047. QCOMPARE(proxy.rowCount(), 3);
  2048. //let's check the selection hasn't changed
  2049. QCOMPARE(selection.selectedIndexes().count(), indexList.count());
  2050. foreach(QPersistentModelIndex index, indexList)
  2051. QVERIFY(selection.isSelected(index));
  2052. }
  2053. void tst_QItemSelectionModel::QTBUG5671_layoutChangedWithAllSelected()
  2054. {
  2055. struct MyFilterModel : public QSortFilterProxyModel
  2056. { // Override sort filter proxy to remove even numbered rows.
  2057. bool filtering;
  2058. virtual bool filterAcceptsRow( int source_row, const QModelIndex& source_parent ) const
  2059. {
  2060. return !filtering || !( source_row & 1 );
  2061. }
  2062. };
  2063. //same as task260134_layoutChangedWithAllSelected but with a sightly bigger model
  2064. enum { cNumRows=30, cNumCols=20 };
  2065. QStandardItemModel model(cNumRows, cNumCols);
  2066. MyFilterModel proxy;
  2067. proxy.filtering = true;
  2068. proxy.setSourceModel(&model);
  2069. QItemSelectionModel selection(&proxy);
  2070. // Populate the tree view.
  2071. for (unsigned int i = 0; i < cNumCols; i++)
  2072. model.setHeaderData( i, Qt::Horizontal, QString::fromLatin1("Column %1").arg(i));
  2073. for (unsigned int r = 0; r < cNumRows; r++) {
  2074. for (unsigned int c = 0; c < cNumCols; c++) {
  2075. model.setData(model.index(r, c, QModelIndex()),
  2076. QString::fromLatin1("r:%1/c:%2").arg(r, c));
  2077. }
  2078. }
  2079. QCOMPARE(model.rowCount(), int(cNumRows));
  2080. QCOMPARE(proxy.rowCount(), int(cNumRows/2));
  2081. selection.select( QItemSelection(proxy.index(0,0), proxy.index(proxy.rowCount() - 1, proxy.columnCount() - 1)), QItemSelectionModel::Select);
  2082. QList<QPersistentModelIndex> indexList;
  2083. foreach(const QModelIndex &id, selection.selectedIndexes())
  2084. indexList << id;
  2085. proxy.filtering = false;
  2086. proxy.invalidate();
  2087. QCOMPARE(proxy.rowCount(), int(cNumRows));
  2088. //let's check the selection hasn't changed
  2089. QCOMPARE(selection.selectedIndexes().count(), indexList.count());
  2090. foreach(QPersistentModelIndex index, indexList)
  2091. QVERIFY(selection.isSelected(index));
  2092. }
  2093. void tst_QItemSelectionModel::QTBUG2804_layoutChangedTreeSelection()
  2094. {
  2095. QStandardItemModel model;
  2096. QStandardItem top1("Child1"), top2("Child2"), top3("Child3");
  2097. QStandardItem sub11("Alpha"), sub12("Beta"), sub13("Gamma"), sub14("Delta"),
  2098. sub21("Alpha"), sub22("Beta"), sub23("Gamma"), sub24("Delta");
  2099. top1.appendColumn(QList<QStandardItem*>() << &sub11 << &sub12 << &sub13 << &sub14);
  2100. top2.appendColumn(QList<QStandardItem*>() << &sub21 << &sub22 << &sub23 << &sub24);
  2101. model.appendColumn(QList<QStandardItem*>() << &top1 << &top2 << &top3);
  2102. QItemSelectionModel selModel(&model);
  2103. selModel.select(sub11.index(), QItemSelectionModel::Select);
  2104. selModel.select(sub12.index(), QItemSelectionModel::Select);
  2105. selModel.select(sub21.index(), QItemSelectionModel::Select);
  2106. selModel.select(sub23.index(), QItemSelectionModel::Select);
  2107. QModelIndexList list = selModel.selectedIndexes();
  2108. QCOMPARE(list.count(), 4);
  2109. model.sort(0); //this will provoke a relayout
  2110. QCOMPARE(selModel.selectedIndexes().count(), 4);
  2111. }
  2112. class RemovalObserver : public QObject
  2113. {
  2114. Q_OBJECT
  2115. QItemSelectionModel *m_itemSelectionModel;
  2116. public:
  2117. RemovalObserver(QItemSelectionModel *selectionModel)
  2118. : m_itemSelectionModel(selectionModel)
  2119. {
  2120. connect(m_itemSelectionModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)), SLOT(selectionChanged(QItemSelection, QItemSelection)));
  2121. }
  2122. public slots:
  2123. void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
  2124. {
  2125. foreach(const QModelIndex &index, deselected.indexes()) {
  2126. QVERIFY(!m_itemSelectionModel->selection().contains(index));
  2127. }
  2128. QVERIFY(m_itemSelectionModel->selection().size() == 2);
  2129. }
  2130. };
  2131. void tst_QItemSelectionModel::deselectRemovedMiddleRange()
  2132. {
  2133. QStandardItemModel model(8, 0);
  2134. for (int row = 0; row < 8; ++row) {
  2135. static const int column = 0;
  2136. QStandardItem *item = new QStandardItem(QString::number(row));
  2137. model.setItem(row, column, item);
  2138. }
  2139. QItemSelectionModel selModel(&model);
  2140. selModel.select(QItemSelection(model.index(3, 0), model.index(6, 0)), QItemSelectionModel::Select);
  2141. QVERIFY(selModel.selection().size() == 1);
  2142. RemovalObserver ro(&selModel);
  2143. QSignalSpy spy(&selModel, SIGNAL(selectionChanged(QItemSelection, QItemSelection)));
  2144. bool ok = model.removeRows(4, 2);
  2145. QVERIFY(ok);
  2146. QVERIFY(spy.size() == 1);
  2147. }
  2148. static QStandardItemModel* getModel(QObject *parent)
  2149. {
  2150. QStandardItemModel *model = new QStandardItemModel(parent);
  2151. for (int i = 0; i < 4; ++i) {
  2152. QStandardItem *parentItem = model->invisibleRootItem();
  2153. QList<QStandardItem*> list;
  2154. for (int j = 0; j < 4; ++j) {
  2155. list.append(new QStandardItem(QString("item %1, %2").arg(i).arg(j)));
  2156. }
  2157. parentItem->appendRow(list);
  2158. parentItem = list.first();
  2159. for (int j = 0; j < 4; ++j) {
  2160. QList<QStandardItem*> list;
  2161. for (int k = 0; k < 4; ++k) {
  2162. list.append(new QStandardItem(QString("item %1, %2").arg(i).arg(j)));
  2163. }
  2164. parentItem->appendRow(list);
  2165. }
  2166. }
  2167. return model;
  2168. }
  2169. enum Result {
  2170. LessThan,
  2171. NotLessThan,
  2172. NotEqual
  2173. };
  2174. Q_DECLARE_METATYPE(Result);
  2175. void tst_QItemSelectionModel::rangeOperatorLessThan_data()
  2176. {
  2177. QTest::addColumn<int>("parent1");
  2178. QTest::addColumn<int>("top1");
  2179. QTest::addColumn<int>("left1");
  2180. QTest::addColumn<int>("bottom1");
  2181. QTest::addColumn<int>("right1");
  2182. QTest::addColumn<int>("parent2");
  2183. QTest::addColumn<int>("top2");
  2184. QTest::addColumn<int>("left2");
  2185. QTest::addColumn<int>("bottom2");
  2186. QTest::addColumn<int>("right2");
  2187. QTest::addColumn<Result>("result");
  2188. QTest::newRow("lt01") << -1 << 0 << 0 << 3 << 3
  2189. << -1 << 0 << 0 << 3 << 3 << NotLessThan;
  2190. QTest::newRow("lt02") << -1 << 0 << 0 << 2 << 3
  2191. << -1 << 0 << 0 << 3 << 3 << LessThan;
  2192. QTest::newRow("lt03") << -1 << 0 << 0 << 3 << 2
  2193. << -1 << 0 << 0 << 3 << 3 << LessThan;
  2194. QTest::newRow("lt04") << -1 << 0 << 0 << 2 << 2
  2195. << -1 << 0 << 0 << 3 << 3 << LessThan;
  2196. QTest::newRow("lt05") << -1 << 0 << 0 << 3 << 3
  2197. << -1 << 0 << 0 << 2 << 3 << NotLessThan;
  2198. QTest::newRow("lt06") << -1 << 0 << 0 << 3 << 3
  2199. << -1 << 0 << 0 << 3 << 2 << NotLessThan;
  2200. QTest::newRow("lt07") << -1 << 0 << 0 << 3 << 3
  2201. << -1 << 0 << 0 << 2 << 2 << NotLessThan;
  2202. QTest::newRow("lt08") << -1 << 0 << 0 << 3 << 3
  2203. << 0 << 0 << 0 << 3 << 3 << NotEqual;
  2204. QTest::newRow("lt09") << 1 << 0 << 0 << 3 << 3
  2205. << 0 << 0 << 0 << 3 << 3 << NotEqual;
  2206. QTest::newRow("lt10") << 1 << 0 << 0 << 1 << 1
  2207. << 0 << 2 << 2 << 3 << 3 << NotEqual;
  2208. QTest::newRow("lt11") << 1 << 2 << 2 << 3 << 3
  2209. << 0 << 0 << 0 << 1 << 1 << NotEqual;
  2210. QTest::newRow("lt12") << -1 << 0 << 0 << 1 << 1
  2211. << -1 << 2 << 2 << 3 << 3 << LessThan;
  2212. QTest::newRow("lt13") << -1 << 2 << 2 << 3 << 3
  2213. << -1 << 0 << 0 << 1 << 1 << NotLessThan;
  2214. QTest::newRow("lt14") << 1 << 0 << 0 << 1 << 1
  2215. << 1 << 2 << 2 << 3 << 3 << LessThan;
  2216. QTest::newRow("lt15") << 1 << 2 << 2 << 3 << 3
  2217. << 1 << 0 << 0 << 1 << 1 << NotLessThan;
  2218. QTest::newRow("lt16") << -1 << 0 << 0 << 2 << 2
  2219. << -1 << 1 << 1 << 3 << 3 << LessThan;
  2220. QTest::newRow("lt17") << -1 << 1 << 1 << 3 << 3
  2221. << -1 << 0 << 0 << 2 << 2 << NotLessThan;
  2222. QTest::newRow("lt18") << 1 << 0 << 0 << 2 << 2
  2223. << 1 << 1 << 1 << 3 << 3 << LessThan;
  2224. QTest::newRow("lt19") << 1 << 1 << 1 << 3 << 3
  2225. << 1 << 0 << 0 << 2 << 2 << NotLessThan;
  2226. }
  2227. void tst_QItemSelectionModel::rangeOperatorLessThan()
  2228. {
  2229. QStandardItemModel *model1 = getModel(this);
  2230. QStandardItemModel *model2 = getModel(this);
  2231. QFETCH(int, parent1);
  2232. QFETCH(int, top1);
  2233. QFETCH(int, left1);
  2234. QFETCH(int, bottom1);
  2235. QFETCH(int, right1);
  2236. QFETCH(int, parent2);
  2237. QFETCH(int, top2);
  2238. QFETCH(int, left2);
  2239. QFETCH(int, bottom2);
  2240. QFETCH(int, right2);
  2241. QFETCH(Result, result);
  2242. QModelIndex p1 = model1->index(parent1, 0);
  2243. QModelIndex tl1 = model1->index(top1, left1, p1);
  2244. QModelIndex br1 = model1->index(bottom1, right1, p1);
  2245. QItemSelectionRange r1(tl1, br1);
  2246. QModelIndex p2 = model1->index(parent2, 0);
  2247. QModelIndex tl2 = model1->index(top2, left2, p2);
  2248. QModelIndex br2 = model1->index(bottom2, right2, p2);
  2249. QItemSelectionRange r2(tl2, br2);
  2250. if (result == LessThan)
  2251. QVERIFY(r1 < r2);
  2252. else if (result == NotLessThan)
  2253. QVERIFY(!(r1 < r2));
  2254. else if (result == NotEqual)
  2255. if (!(r1 < r2))
  2256. QVERIFY(r2 < r1);
  2257. // Ranges in different models are always non-equal
  2258. QModelIndex p3 = model2->index(parent1, 0);
  2259. QModelIndex tl3 = model2->index(top1, left1, p3);
  2260. QModelIndex br3 = model2->index(bottom1, right1, p3);
  2261. QItemSelectionRange r3(tl3, br3);
  2262. if (!(r1 < r3))
  2263. QVERIFY(r3 < r1);
  2264. if (!(r2 < r3))
  2265. QVERIFY(r3 < r2);
  2266. QModelIndex p4 = model2->index(parent2, 0);
  2267. QModelIndex tl4 = model2->index(top2, left2, p4);
  2268. QModelIndex br4 = model2->index(bottom2, right2, p4);
  2269. QItemSelectionRange r4(tl4, br4);
  2270. if (!(r1 < r4))
  2271. QVERIFY(r4 < r1);
  2272. if (!(r2 < r4))
  2273. QVERIFY(r4 < r2);
  2274. }
  2275. void tst_QItemSelectionModel::testDifferentModels()
  2276. {
  2277. QStandardItemModel model1;
  2278. QStandardItemModel model2;
  2279. QStandardItem top11("Child1"), top12("Child2"), top13("Child3");
  2280. QStandardItem top21("Child1"), top22("Child2"), top23("Child3");
  2281. model1.appendColumn(QList<QStandardItem*>() << &top11 << &top12 << &top13);
  2282. model2.appendColumn(QList<QStandardItem*>() << &top21 << &top22 << &top23);
  2283. QModelIndex topIndex1 = model1.index(0, 0);
  2284. QModelIndex bottomIndex1 = model1.index(2, 0);
  2285. QModelIndex topIndex2 = model2.index(0, 0);
  2286. QItemSelectionRange range(topIndex1, bottomIndex1);
  2287. QVERIFY(range.intersects(QItemSelectionRange(topIndex1, topIndex1)));
  2288. QVERIFY(!range.intersects(QItemSelectionRange(topIndex2, topIndex2)));
  2289. QItemSelection newSelection;
  2290. QItemSelection::split(range, QItemSelectionRange(topIndex2, topIndex2), &newSelection);
  2291. QVERIFY(newSelection.isEmpty());
  2292. }
  2293. class SelectionObserver : public QObject
  2294. {
  2295. Q_OBJECT
  2296. public:
  2297. SelectionObserver(QAbstractItemModel *model, QObject *parent = 0)
  2298. : QObject(parent), m_model(model), m_selectionModel(0)
  2299. {
  2300. connect(model, SIGNAL(modelReset()), SLOT(modelReset()));
  2301. }
  2302. void setSelectionModel(QItemSelectionModel *selectionModel)
  2303. {
  2304. m_selectionModel = selectionModel;
  2305. connect(m_selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection)));
  2306. }
  2307. private slots:
  2308. void modelReset()
  2309. {
  2310. const QModelIndex idx = m_model->index(2, 0);
  2311. QVERIFY(idx.isValid());
  2312. m_selectionModel->select(QItemSelection(idx, idx), QItemSelectionModel::Clear);
  2313. }
  2314. void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
  2315. {
  2316. foreach(const QItemSelectionRange &range, selected)
  2317. QVERIFY(range.isValid());
  2318. foreach(const QItemSelectionRange &range, deselected)
  2319. QVERIFY(range.isValid());
  2320. }
  2321. private:
  2322. QAbstractItemModel *m_model;
  2323. QItemSelectionModel *m_selectionModel;
  2324. };
  2325. void tst_QItemSelectionModel::testValidRangesInSelectionsAfterReset()
  2326. {
  2327. QStringListModel model;
  2328. QStringList strings;
  2329. strings << "one"
  2330. << "two"
  2331. << "three"
  2332. << "four"
  2333. << "five";
  2334. model.setStringList(strings);
  2335. SelectionObserver observer(&model);
  2336. QItemSelectionModel selectionModel(&model);
  2337. selectionModel.select(QItemSelection(model.index(1, 0), model.index(3, 0)), QItemSelectionModel::Select);
  2338. // Cause d->ranges to contain something.
  2339. model.insertRows(2, 1);
  2340. observer.setSelectionModel(&selectionModel);
  2341. model.setStringList(strings);
  2342. }
  2343. class DuplicateItemSelectionModel : public QItemSelectionModel
  2344. {
  2345. Q_OBJECT
  2346. public:
  2347. DuplicateItemSelectionModel(QItemSelectionModel *target, QAbstractItemModel *model, QObject *parent = 0)
  2348. : QItemSelectionModel(model, parent), m_target(target)
  2349. {
  2350. }
  2351. void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)
  2352. {
  2353. QItemSelectionModel::select(selection, command);
  2354. m_target->select(selection, command);
  2355. }
  2356. using QItemSelectionModel::select;
  2357. private:
  2358. QItemSelectionModel *m_target;
  2359. };
  2360. void tst_QItemSelectionModel::testChainedSelectionClear()
  2361. {
  2362. QStringListModel model(QStringList() << "Apples" << "Pears");
  2363. QItemSelectionModel selectionModel(&model, 0);
  2364. DuplicateItemSelectionModel duplicate(&selectionModel, &model, 0);
  2365. duplicate.select(model.index(0, 0), QItemSelectionModel::Select);
  2366. {
  2367. QModelIndexList selectedIndexes = selectionModel.selection().indexes();
  2368. QModelIndexList duplicatedIndexes = duplicate.selection().indexes();
  2369. QVERIFY(selectedIndexes.size() == duplicatedIndexes.size());
  2370. QVERIFY(selectedIndexes.size() == 1);
  2371. QVERIFY(selectedIndexes.first() == model.index(0, 0));
  2372. }
  2373. duplicate.clearSelection();
  2374. {
  2375. QModelIndexList selectedIndexes = selectionModel.selection().indexes();
  2376. QModelIndexList duplicatedIndexes = duplicate.selection().indexes();
  2377. QVERIFY(selectedIndexes.size() == duplicatedIndexes.size());
  2378. QVERIFY(selectedIndexes.size() == 0);
  2379. }
  2380. }
  2381. QTEST_MAIN(tst_QItemSelectionModel)
  2382. #include "tst_qitemselectionmodel.moc"