1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QIdentityProxyModel> |
30 | #include <QLabel> |
31 | #include <QLineEdit> |
32 | #include <QScrollBar> |
33 | #include <QSignalSpy> |
34 | #include <QSortFilterProxyModel> |
35 | #include <QStandardItemModel> |
36 | #include <QStringListModel> |
37 | #include <QStyledItemDelegate> |
38 | #include <QTableView> |
39 | #include <QTest> |
40 | #include <private/qapplication_p.h> |
41 | #include <private/qtablewidget_p.h> |
42 | #include <private/qtesthelpers_p.h> |
43 | #if QT_CONFIG(textmarkdownwriter) |
44 | #include <private/qtextmarkdownwriter_p.h> |
45 | #endif |
46 | |
47 | |
48 | using namespace QTestPrivate; |
49 | |
50 | #ifdef QT_BUILD_INTERNAL |
51 | #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \ |
52 | QVERIFY(static_cast<QTableViewPrivate*>(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency()) |
53 | #else |
54 | #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) (void)false |
55 | #endif |
56 | |
57 | Q_DECLARE_METATYPE(Qt::Key); |
58 | Q_DECLARE_METATYPE(Qt::KeyboardModifier); |
59 | Q_DECLARE_METATYPE(QItemSelectionModel::SelectionFlag); |
60 | using BoolList = QVector<bool>; |
61 | using IntList = QVector<int>; |
62 | using KeyList = QVector<Qt::Key>; |
63 | using SpanList = QVector<QRect>; |
64 | |
65 | class QtTestTableModel: public QAbstractTableModel |
66 | { |
67 | Q_OBJECT |
68 | |
69 | signals: |
70 | void invalidIndexEncountered() const; |
71 | |
72 | public slots: |
73 | bool submit() override { ++submit_count; return QAbstractTableModel::submit(); } |
74 | |
75 | public: |
76 | QtTestTableModel(int rows = 0, int columns = 0, QObject *parent = nullptr) |
77 | : QAbstractTableModel(parent), row_count(rows), column_count(columns) |
78 | {} |
79 | |
80 | int rowCount(const QModelIndex& = QModelIndex()) const override |
81 | { |
82 | return row_count; |
83 | } |
84 | |
85 | int columnCount(const QModelIndex& = QModelIndex()) const override |
86 | { |
87 | return column_count; |
88 | } |
89 | |
90 | bool isEditable(const QModelIndex &) const { return true; } |
91 | |
92 | Qt::ItemFlags flags(const QModelIndex &index) const override |
93 | { |
94 | Qt::ItemFlags index_flags = QAbstractTableModel::flags(index); |
95 | if (disabled_rows.contains(value: index.row()) |
96 | || disabled_columns.contains(value: index.column())) |
97 | index_flags &= ~Qt::ItemIsEnabled; |
98 | return index_flags; |
99 | } |
100 | |
101 | void disableRow(int row) |
102 | { |
103 | disabled_rows.insert(value: row); |
104 | } |
105 | |
106 | void enableRow(int row) |
107 | { |
108 | disabled_rows.remove(value: row); |
109 | } |
110 | |
111 | void disableColumn(int column) |
112 | { |
113 | disabled_columns.insert(value: column); |
114 | } |
115 | |
116 | void enableColumn(int column) |
117 | { |
118 | disabled_columns.remove(value: column); |
119 | } |
120 | |
121 | QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override |
122 | { |
123 | if (!idx.isValid() || idx.row() >= row_count || idx.column() >= column_count) { |
124 | qWarning() << "Invalid modelIndex [%d,%d,%p]" << idx; |
125 | emit invalidIndexEncountered(); |
126 | return QVariant(); |
127 | } |
128 | |
129 | if (role == Qt::DisplayRole || role == Qt::EditRole) { |
130 | return QLatin1Char('[') + QString::number(idx.row()) + QLatin1Char(',') |
131 | + QString::number(idx.column()) + QLatin1String(",0]" ); |
132 | } |
133 | |
134 | return QVariant(); |
135 | } |
136 | |
137 | bool insertRows(int start, int count, const QModelIndex &parent = QModelIndex()) override |
138 | { |
139 | if (start < 0 || start > row_count) |
140 | return false; |
141 | |
142 | beginInsertRows(parent, first: start, last: start + count - 1); |
143 | row_count += count; |
144 | endInsertRows(); |
145 | return true; |
146 | } |
147 | |
148 | bool removeRows(int start, int count, const QModelIndex &parent = QModelIndex()) override |
149 | { |
150 | if (start < 0 || start >= row_count || row_count < count) |
151 | return false; |
152 | |
153 | beginRemoveRows(parent, first: start, last: start + count - 1); |
154 | row_count -= count; |
155 | endRemoveRows(); |
156 | return true; |
157 | } |
158 | |
159 | void removeLastRow() |
160 | { |
161 | beginRemoveRows(parent: QModelIndex(), first: row_count - 1, last: row_count - 1); |
162 | --row_count; |
163 | endRemoveRows(); |
164 | } |
165 | |
166 | void removeAllRows() |
167 | { |
168 | beginRemoveRows(parent: QModelIndex(), first: 0, last: row_count - 1); |
169 | row_count = 0; |
170 | endRemoveRows(); |
171 | } |
172 | |
173 | bool insertColumns(int start, int count, const QModelIndex &parent = QModelIndex()) override |
174 | { |
175 | if (start < 0 || start > column_count) |
176 | return false; |
177 | |
178 | beginInsertColumns(parent, first: start, last: start + count - 1); |
179 | column_count += count; |
180 | endInsertColumns(); |
181 | return true; |
182 | } |
183 | |
184 | bool removeColumns(int start, int count, const QModelIndex &parent = QModelIndex()) override |
185 | { |
186 | if (start < 0 || start >= column_count || column_count < count) |
187 | return false; |
188 | |
189 | beginRemoveColumns(parent, first: start, last: start + count - 1); |
190 | column_count -= count; |
191 | endRemoveColumns(); |
192 | return true; |
193 | } |
194 | |
195 | void removeLastColumn() |
196 | { |
197 | beginRemoveColumns(parent: QModelIndex(), first: column_count - 1, last: column_count - 1); |
198 | --column_count; |
199 | endRemoveColumns(); |
200 | } |
201 | |
202 | void removeAllColumns() |
203 | { |
204 | beginRemoveColumns(parent: QModelIndex(), first: 0, last: column_count - 1); |
205 | column_count = 0; |
206 | endRemoveColumns(); |
207 | } |
208 | |
209 | bool canFetchMore(const QModelIndex &) const override |
210 | { |
211 | return can_fetch_more; |
212 | } |
213 | |
214 | void fetchMore(const QModelIndex &) override |
215 | { |
216 | ++fetch_more_count; |
217 | } |
218 | |
219 | QSet<int> disabled_rows; |
220 | QSet<int> disabled_columns; |
221 | int row_count; |
222 | int column_count; |
223 | int submit_count = 0; |
224 | int fetch_more_count = 0; |
225 | bool can_fetch_more = false; |
226 | }; |
227 | |
228 | class QtTestTableView : public QTableView |
229 | { |
230 | Q_OBJECT |
231 | public: |
232 | using QTableView::QTableView; |
233 | |
234 | void setModel(QAbstractItemModel *model) override |
235 | { |
236 | QTableView::setModel(model); |
237 | connect(sender: selectionModel(), signal: &QItemSelectionModel::currentChanged, |
238 | receiver: this, slot: &QtTestTableView::slotCurrentChanged); |
239 | connect(sender: selectionModel(), signal: &QItemSelectionModel::selectionChanged, |
240 | receiver: this, slot: &QtTestTableView::itemSelectionChanged); |
241 | // Allow small sections in this test, since this test was made before we correctly enforced minimum sizes. |
242 | horizontalHeader()->setMinimumSectionSize(0); |
243 | verticalHeader()->setMinimumSectionSize(0); |
244 | } |
245 | |
246 | using QTableView::moveCursor; |
247 | using QTableView::isIndexHidden; |
248 | using QTableView::setSelection; |
249 | using QTableView::selectedIndexes; |
250 | using QTableView::sizeHintForRow; |
251 | using QTableView::viewOptions; |
252 | |
253 | bool checkSignalOrder = false; |
254 | public slots: |
255 | void slotCurrentChanged(QModelIndex, QModelIndex) { |
256 | hasCurrentChanged++; |
257 | if (checkSignalOrder) |
258 | QVERIFY(hasCurrentChanged > hasSelectionChanged); |
259 | } |
260 | |
261 | void itemSelectionChanged(QItemSelection , QItemSelection ) { |
262 | hasSelectionChanged++; |
263 | if (checkSignalOrder) |
264 | QVERIFY(hasCurrentChanged >= hasSelectionChanged); |
265 | } |
266 | private: |
267 | int hasCurrentChanged = 0; |
268 | int hasSelectionChanged = 0; |
269 | |
270 | friend class tst_QTableView; |
271 | friend struct QMetaTypeId<QtTestTableView::CursorAction>; |
272 | }; |
273 | Q_DECLARE_METATYPE(QtTestTableView::CursorAction); |
274 | |
275 | class QtTestItemDelegate : public QStyledItemDelegate |
276 | { |
277 | public: |
278 | QSize sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const override |
279 | { |
280 | return hint; |
281 | } |
282 | |
283 | QSize hint; |
284 | }; |
285 | |
286 | class tst_QTableView : public QObject |
287 | { |
288 | Q_OBJECT |
289 | |
290 | private: |
291 | using CursorActionList = QVector<QtTestTableView::CursorAction>; |
292 | private slots: |
293 | void getSetCheck(); |
294 | |
295 | void noDelegate(); |
296 | void noModel(); |
297 | void emptyModel(); |
298 | |
299 | void removeRows_data(); |
300 | void removeRows(); |
301 | |
302 | void removeColumns_data(); |
303 | void removeColumns(); |
304 | |
305 | void keyboardNavigation_data(); |
306 | void keyboardNavigation(); |
307 | |
308 | void headerSections_data(); |
309 | void headerSections(); |
310 | |
311 | void moveCursor_data(); |
312 | void moveCursor(); |
313 | |
314 | void moveCursorStrikesBack_data(); |
315 | void moveCursorStrikesBack(); |
316 | |
317 | void moveCursorBiggerJump(); |
318 | |
319 | void hideRows_data(); |
320 | void hideRows(); |
321 | |
322 | void hideColumns_data(); |
323 | void hideColumns(); |
324 | |
325 | void selection_data(); |
326 | void selection(); |
327 | |
328 | void selectRow_data(); |
329 | void selectRow(); |
330 | |
331 | void selectColumn_data(); |
332 | void selectColumn(); |
333 | |
334 | void selectall_data(); |
335 | void selectall(); |
336 | |
337 | void visualRect_data(); |
338 | void visualRect(); |
339 | |
340 | void fetchMore(); |
341 | void setHeaders(); |
342 | |
343 | void resizeRowsToContents_data(); |
344 | void resizeRowsToContents(); |
345 | |
346 | void resizeColumnsToContents_data(); |
347 | void resizeColumnsToContents(); |
348 | |
349 | void rowViewportPosition_data(); |
350 | void rowViewportPosition(); |
351 | |
352 | void rowAt_data(); |
353 | void rowAt(); |
354 | |
355 | void rowHeight_data(); |
356 | void rowHeight(); |
357 | |
358 | void columnViewportPosition_data(); |
359 | void columnViewportPosition(); |
360 | |
361 | void columnAt_data(); |
362 | void columnAt(); |
363 | |
364 | void columnWidth_data(); |
365 | void columnWidth(); |
366 | |
367 | void hiddenRow_data(); |
368 | void hiddenRow(); |
369 | |
370 | void hiddenColumn_data(); |
371 | void hiddenColumn(); |
372 | |
373 | void sortingEnabled_data(); |
374 | void sortingEnabled(); |
375 | |
376 | void sortByColumn_data(); |
377 | void sortByColumn(); |
378 | |
379 | void scrollTo_data(); |
380 | void scrollTo(); |
381 | |
382 | void indexAt_data(); |
383 | void indexAt(); |
384 | |
385 | void span_data(); |
386 | void span(); |
387 | void spans(); |
388 | void spans_data(); |
389 | void spansAfterRowInsertion(); |
390 | void spansAfterColumnInsertion(); |
391 | void spansAfterRowRemoval(); |
392 | void spansAfterColumnRemoval(); |
393 | void editSpanFromDirections_data(); |
394 | void editSpanFromDirections(); |
395 | |
396 | void checkHeaderReset(); |
397 | void checkHeaderMinSize(); |
398 | |
399 | void resizeToContents(); |
400 | |
401 | void tabFocus(); |
402 | void bigModel(); |
403 | void selectionSignal(); |
404 | void setCurrentIndex(); |
405 | |
406 | // task-specific tests: |
407 | void task173773_updateVerticalHeader(); |
408 | void task227953_setRootIndex(); |
409 | void task240266_veryBigColumn(); |
410 | void task248688_autoScrollNavigation(); |
411 | void task259308_scrollVerticalHeaderSwappedSections(); |
412 | void task191545_dragSelectRows(); |
413 | void taskQTBUG_5062_spansInconsistency(); |
414 | void taskQTBUG_4516_clickOnRichTextLabel(); |
415 | #if QT_CONFIG(wheelevent) |
416 | void taskQTBUG_5237_wheelEventOnHeader(); |
417 | #endif |
418 | void taskQTBUG_8585_crashForNoGoodReason(); |
419 | void taskQTBUG_7774_RtoLVisualRegionForSelection(); |
420 | void taskQTBUG_8777_scrollToSpans(); |
421 | void taskQTBUG_10169_sizeHintForRow(); |
422 | void taskQTBUG_30653_doItemsLayout(); |
423 | void taskQTBUG_50171_selectRowAfterSwapColumns(); |
424 | void deselectRow(); |
425 | |
426 | #if QT_CONFIG(wheelevent) |
427 | void mouseWheel_data(); |
428 | void mouseWheel(); |
429 | #endif |
430 | |
431 | void addColumnWhileEditing(); |
432 | void task234926_setHeaderSorting(); |
433 | |
434 | void changeHeaderData(); |
435 | void viewOptions(); |
436 | |
437 | void taskQTBUG_7232_AllowUserToControlSingleStep(); |
438 | |
439 | #if QT_CONFIG(textmarkdownwriter) |
440 | void markdownWriter(); |
441 | #endif |
442 | }; |
443 | |
444 | // Testing get/set functions |
445 | void tst_QTableView::getSetCheck() |
446 | { |
447 | QTableView obj1; |
448 | |
449 | obj1.setSortingEnabled(false); |
450 | QCOMPARE(false, obj1.isSortingEnabled()); |
451 | obj1.setSortingEnabled(true); |
452 | QCOMPARE(true, obj1.isSortingEnabled()); |
453 | |
454 | obj1.setShowGrid(false); |
455 | QCOMPARE(false, obj1.showGrid()); |
456 | obj1.setShowGrid(true); |
457 | QCOMPARE(true, obj1.showGrid()); |
458 | |
459 | obj1.setGridStyle(Qt::NoPen); |
460 | QCOMPARE(Qt::NoPen, obj1.gridStyle()); |
461 | obj1.setGridStyle(Qt::SolidLine); |
462 | QCOMPARE(Qt::SolidLine, obj1.gridStyle()); |
463 | |
464 | obj1.setRootIndex(QModelIndex()); |
465 | QCOMPARE(QModelIndex(), obj1.rootIndex()); |
466 | QStandardItemModel model(10, 10); |
467 | obj1.setModel(&model); |
468 | QModelIndex index = model.index(row: 0, column: 0); |
469 | obj1.setRootIndex(index); |
470 | QCOMPARE(index, obj1.rootIndex()); |
471 | |
472 | QHeaderView *var1 = new QHeaderView(Qt::Horizontal); |
473 | obj1.setHorizontalHeader(var1); |
474 | QCOMPARE(var1, obj1.horizontalHeader()); |
475 | obj1.setHorizontalHeader(nullptr); |
476 | QCOMPARE(var1, obj1.horizontalHeader()); |
477 | delete var1; |
478 | |
479 | QHeaderView *var2 = new QHeaderView(Qt::Vertical); |
480 | obj1.setVerticalHeader(var2); |
481 | QCOMPARE(var2, obj1.verticalHeader()); |
482 | obj1.setVerticalHeader(nullptr); |
483 | QCOMPARE(var2, obj1.verticalHeader()); |
484 | delete var2; |
485 | |
486 | QCOMPARE(obj1.isCornerButtonEnabled(), true); |
487 | obj1.setCornerButtonEnabled(false); |
488 | QCOMPARE(obj1.isCornerButtonEnabled(), false); |
489 | } |
490 | void tst_QTableView::noDelegate() |
491 | { |
492 | QtTestTableModel model(3, 3); |
493 | QTableView view; |
494 | view.setModel(&model); |
495 | view.setItemDelegate(nullptr); |
496 | view.show(); |
497 | } |
498 | |
499 | void tst_QTableView::noModel() |
500 | { |
501 | QTableView view; |
502 | view.show(); |
503 | } |
504 | |
505 | void tst_QTableView::emptyModel() |
506 | { |
507 | QtTestTableModel model; |
508 | QTableView view; |
509 | QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered); |
510 | view.setModel(&model); |
511 | view.show(); |
512 | QCOMPARE(spy.count(), 0); |
513 | } |
514 | |
515 | void tst_QTableView::removeRows_data() |
516 | { |
517 | QTest::addColumn<int>(name: "rowCount" ); |
518 | QTest::addColumn<int>(name: "columnCount" ); |
519 | |
520 | QTest::newRow(dataTag: "2x2" ) << 2 << 2; |
521 | QTest::newRow(dataTag: "10x10" ) << 10 << 10; |
522 | } |
523 | |
524 | void tst_QTableView::removeRows() |
525 | { |
526 | QFETCH(int, rowCount); |
527 | QFETCH(int, columnCount); |
528 | |
529 | QtTestTableModel model(rowCount, columnCount); |
530 | QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered); |
531 | |
532 | QTableView view; |
533 | view.setModel(&model); |
534 | view.show(); |
535 | |
536 | model.removeLastRow(); |
537 | QCOMPARE(spy.count(), 0); |
538 | |
539 | model.removeAllRows(); |
540 | QCOMPARE(spy.count(), 0); |
541 | } |
542 | |
543 | void tst_QTableView::removeColumns_data() |
544 | { |
545 | QTest::addColumn<int>(name: "rowCount" ); |
546 | QTest::addColumn<int>(name: "columnCount" ); |
547 | |
548 | QTest::newRow(dataTag: "2x2" ) << 2 << 2; |
549 | QTest::newRow(dataTag: "10x10" ) << 10 << 10; |
550 | } |
551 | |
552 | void tst_QTableView::removeColumns() |
553 | { |
554 | QFETCH(int, rowCount); |
555 | QFETCH(int, columnCount); |
556 | |
557 | QtTestTableModel model(rowCount, columnCount); |
558 | QSignalSpy spy(&model, &QtTestTableModel::invalidIndexEncountered); |
559 | |
560 | QTableView view; |
561 | view.setModel(&model); |
562 | view.show(); |
563 | |
564 | model.removeLastColumn(); |
565 | QCOMPARE(spy.count(), 0); |
566 | |
567 | model.removeAllColumns(); |
568 | QCOMPARE(spy.count(), 0); |
569 | } |
570 | |
571 | void tst_QTableView::keyboardNavigation_data() |
572 | { |
573 | QTest::addColumn<int>(name: "rowCount" ); |
574 | QTest::addColumn<int>(name: "columnCount" ); |
575 | QTest::addColumn<bool>(name: "tabKeyNavigation" ); |
576 | QTest::addColumn<KeyList>(name: "keyPresses" ); |
577 | |
578 | const KeyList keyList { |
579 | Qt::Key_Up, Qt::Key_Up, Qt::Key_Right, Qt::Key_Right, |
580 | Qt::Key_Up, Qt::Key_Left, Qt::Key_Left, Qt::Key_Up, |
581 | Qt::Key_Down, Qt::Key_Up, Qt::Key_Up, Qt::Key_Up, |
582 | Qt::Key_Up, Qt::Key_Up, Qt::Key_Up, Qt::Key_Left, |
583 | Qt::Key_Left, Qt::Key_Up, Qt::Key_Down, Qt::Key_Down, |
584 | Qt::Key_Tab, Qt::Key_Backtab}; |
585 | |
586 | QTest::newRow(dataTag: "16x16 model" ) << 16 << 16 << true << keyList; |
587 | QTest::newRow(dataTag: "no tab" ) << 8 << 8 << false << keyList; |
588 | } |
589 | |
590 | void tst_QTableView::keyboardNavigation() |
591 | { |
592 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
593 | QSKIP("Wayland: This fails. Figure out why." ); |
594 | |
595 | QFETCH(int, rowCount); |
596 | QFETCH(int, columnCount); |
597 | QFETCH(bool, tabKeyNavigation); |
598 | QFETCH(const KeyList, keyPresses); |
599 | |
600 | QtTestTableModel model(rowCount, columnCount); |
601 | QTableView view; |
602 | view.setModel(&model); |
603 | |
604 | view.setTabKeyNavigation(tabKeyNavigation); |
605 | QModelIndex index = model.index(row: rowCount - 1, column: columnCount - 1); |
606 | view.setCurrentIndex(index); |
607 | |
608 | view.show(); |
609 | QApplication::setActiveWindow(&view); |
610 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
611 | |
612 | int row = rowCount - 1; |
613 | int column = columnCount - 1; |
614 | for (Qt::Key key : keyPresses) { |
615 | |
616 | switch (key) { |
617 | case Qt::Key_Up: |
618 | row = qMax(a: 0, b: row - 1); |
619 | break; |
620 | case Qt::Key_Down: |
621 | row = qMin(a: rowCount - 1, b: row + 1); |
622 | break; |
623 | case Qt::Key_Backtab: |
624 | if (!tabKeyNavigation) |
625 | break; |
626 | Q_FALLTHROUGH(); |
627 | case Qt::Key_Left: |
628 | column = qMax(a: 0, b: column - 1); |
629 | break; |
630 | case Qt::Key_Tab: |
631 | if (!tabKeyNavigation) |
632 | break; |
633 | Q_FALLTHROUGH(); |
634 | case Qt::Key_Right: |
635 | column = qMin(a: columnCount - 1, b: column + 1); |
636 | break; |
637 | default: |
638 | break; |
639 | } |
640 | |
641 | QTest::keyClick(widget: &view, key); |
642 | QApplication::processEvents(); |
643 | |
644 | QModelIndex index = model.index(row, column); |
645 | QCOMPARE(view.currentIndex(), index); |
646 | } |
647 | } |
648 | |
649 | void tst_QTableView::() |
650 | { |
651 | QTest::addColumn<int>(name: "rowCount" ); |
652 | QTest::addColumn<int>(name: "columnCount" ); |
653 | QTest::addColumn<int>(name: "row" ); |
654 | QTest::addColumn<int>(name: "column" ); |
655 | QTest::addColumn<int>(name: "rowHeight" ); |
656 | QTest::addColumn<int>(name: "columnWidth" ); |
657 | |
658 | QTest::newRow(dataTag: "" ) << 10 << 10 << 5 << 5 << 30 << 30; |
659 | } |
660 | |
661 | void tst_QTableView::() |
662 | { |
663 | QFETCH(int, rowCount); |
664 | QFETCH(int, columnCount); |
665 | QFETCH(int, row); |
666 | QFETCH(int, column); |
667 | QFETCH(int, rowHeight); |
668 | QFETCH(int, columnWidth); |
669 | |
670 | QtTestTableModel model(rowCount, columnCount); |
671 | |
672 | QTableView view; |
673 | QHeaderView * = view.horizontalHeader(); |
674 | QHeaderView * = view.verticalHeader(); |
675 | |
676 | view.setModel(&model); |
677 | hheader->setMinimumSectionSize(columnWidth); |
678 | vheader->setMinimumSectionSize(rowHeight); |
679 | view.show(); |
680 | |
681 | hheader->doItemsLayout(); |
682 | vheader->doItemsLayout(); |
683 | |
684 | QCOMPARE(hheader->count(), model.columnCount()); |
685 | QCOMPARE(vheader->count(), model.rowCount()); |
686 | |
687 | view.setRowHeight(row, height: rowHeight); |
688 | QCOMPARE(view.rowHeight(row), rowHeight); |
689 | view.hideRow(row); |
690 | QCOMPARE(view.rowHeight(row), 0); |
691 | view.showRow(row); |
692 | QCOMPARE(view.rowHeight(row), rowHeight); |
693 | |
694 | view.setColumnWidth(column, width: columnWidth); |
695 | QCOMPARE(view.columnWidth(column), columnWidth); |
696 | view.hideColumn(column); |
697 | QCOMPARE(view.columnWidth(column), 0); |
698 | view.showColumn(column); |
699 | QCOMPARE(view.columnWidth(column), columnWidth); |
700 | } |
701 | |
702 | typedef QPair<int,int> IntPair; |
703 | |
704 | void tst_QTableView::moveCursor_data() |
705 | { |
706 | QTest::addColumn<int>(name: "rowCount" ); |
707 | QTest::addColumn<int>(name: "columnCount" ); |
708 | QTest::addColumn<int>(name: "hideRow" ); |
709 | QTest::addColumn<int>(name: "hideColumn" ); |
710 | |
711 | QTest::addColumn<int>(name: "startRow" ); |
712 | QTest::addColumn<int>(name: "startColumn" ); |
713 | |
714 | QTest::addColumn<QtTestTableView::CursorAction>(name: "cursorMoveAction" ); |
715 | QTest::addColumn<Qt::KeyboardModifier>(name: "modifier" ); |
716 | |
717 | QTest::addColumn<int>(name: "expectedRow" ); |
718 | QTest::addColumn<int>(name: "expectedColumn" ); |
719 | QTest::addColumn<IntPair>(name: "moveRow" ); |
720 | QTest::addColumn<IntPair>(name: "moveColumn" ); |
721 | |
722 | // MoveRight |
723 | QTest::newRow(dataTag: "MoveRight (0,0)" ) |
724 | << 4 << 4 << -1 << -1 |
725 | << 0 << 0 |
726 | << QtTestTableView::MoveRight << Qt::NoModifier |
727 | << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
728 | |
729 | QTest::newRow(dataTag: "MoveRight (3,0)" ) |
730 | << 4 << 4 << -1 << -1 |
731 | << 3 << 0 |
732 | << QtTestTableView::MoveRight << Qt::NoModifier |
733 | << 3 << 1 << IntPair(0,0) << IntPair(0,0); |
734 | |
735 | QTest::newRow(dataTag: "MoveRight (3,3)" ) |
736 | << 4 << 4 << -1 << -1 |
737 | << 3 << 3 |
738 | << QtTestTableView::MoveRight << Qt::NoModifier |
739 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); // ### |
740 | |
741 | QTest::newRow(dataTag: "MoveRight, hidden column 1 (0,0)" ) |
742 | << 4 << 4 << -1 << 1 |
743 | << 0 << 0 |
744 | << QtTestTableView::MoveRight << Qt::NoModifier |
745 | << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
746 | |
747 | QTest::newRow(dataTag: "MoveRight, hidden column 3 (0,2)" ) |
748 | << 4 << 4 << -1 << 3 |
749 | << 0 << 2 |
750 | << QtTestTableView::MoveRight << Qt::NoModifier |
751 | << 0 << 2 << IntPair(0,0) << IntPair(0,0); // ### |
752 | |
753 | // MoveNext should in addition wrap |
754 | QTest::newRow(dataTag: "MoveNext (0,0)" ) |
755 | << 4 << 4 << -1 << -1 |
756 | << 0 << 0 |
757 | << QtTestTableView::MoveNext << Qt::NoModifier |
758 | << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
759 | |
760 | QTest::newRow(dataTag: "MoveNext (0,2)" ) |
761 | << 4 << 4 << -1 << -1 |
762 | << 0 << 2 |
763 | << QtTestTableView::MoveNext << Qt::NoModifier |
764 | << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
765 | |
766 | QTest::newRow(dataTag: "MoveNext, wrap (0,3)" ) |
767 | << 4 << 4 << -1 << -1 |
768 | << 0 << 3 |
769 | << QtTestTableView::MoveNext << Qt::NoModifier |
770 | << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
771 | |
772 | QTest::newRow(dataTag: "MoveNext, wrap (3,3)" ) |
773 | << 4 << 4 << -1 << -1 |
774 | << 3 << 3 |
775 | << QtTestTableView::MoveNext << Qt::NoModifier |
776 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
777 | |
778 | QTest::newRow(dataTag: "MoveNext, hidden column 1 (0,0)" ) |
779 | << 4 << 4 << -1 << 1 |
780 | << 0 << 0 |
781 | << QtTestTableView::MoveNext << Qt::NoModifier |
782 | << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
783 | |
784 | QTest::newRow(dataTag: "MoveNext, wrap, hidden column 3 (0,2)" ) |
785 | << 4 << 4 << -1 << 3 |
786 | << 0 << 2 |
787 | << QtTestTableView::MoveNext << Qt::NoModifier |
788 | << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
789 | |
790 | QTest::newRow(dataTag: "MoveNext, wrap, hidden column 3 (3,2)" ) |
791 | << 4 << 4 << -1 << 3 |
792 | << 3 << 2 |
793 | << QtTestTableView::MoveNext << Qt::NoModifier |
794 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
795 | |
796 | QTest::newRow(dataTag: "MoveNext, wrapy, wrapx, hidden column 3, hidden row 3 (2,2)" ) |
797 | << 4 << 4 << 3 << 3 |
798 | << 2 << 2 |
799 | << QtTestTableView::MoveNext << Qt::NoModifier |
800 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
801 | |
802 | QTest::newRow(dataTag: "MoveNext, wrap, hidden column 2, moved column from 3 to 0. (0,2)" ) |
803 | << 4 << 4 << -1 << 2 |
804 | << 0 << 2 |
805 | << QtTestTableView::MoveNext << Qt::NoModifier |
806 | << 1 << 3 << IntPair(0,0) << IntPair(3,0); |
807 | |
808 | // MoveLeft |
809 | QTest::newRow(dataTag: "MoveLeft (0,0)" ) |
810 | << 4 << 4 << -1 << -1 |
811 | << 0 << 0 |
812 | << QtTestTableView::MoveLeft << Qt::NoModifier |
813 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
814 | |
815 | QTest::newRow(dataTag: "MoveLeft (0,3)" ) |
816 | << 4 << 4 << -1 << -1 |
817 | << 0 << 3 |
818 | << QtTestTableView::MoveLeft << Qt::NoModifier |
819 | << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
820 | |
821 | QTest::newRow(dataTag: "MoveLeft (1,0)" ) |
822 | << 4 << 4 << -1 << -1 |
823 | << 1 << 0 |
824 | << QtTestTableView::MoveLeft << Qt::NoModifier |
825 | << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
826 | |
827 | QTest::newRow(dataTag: "MoveLeft, hidden column 0 (0,2)" ) |
828 | << 4 << 4 << -1 << 1 |
829 | << 0 << 2 |
830 | << QtTestTableView::MoveLeft << Qt::NoModifier |
831 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
832 | |
833 | QTest::newRow(dataTag: "MoveLeft, hidden column 0 (0,1)" ) |
834 | << 4 << 4 << -1 << 0 |
835 | << 0 << 1 |
836 | << QtTestTableView::MoveLeft << Qt::NoModifier |
837 | << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
838 | |
839 | // MovePrevious should in addition wrap |
840 | QTest::newRow(dataTag: "MovePrevious (0,3)" ) |
841 | << 4 << 4 << -1 << -1 |
842 | << 0 << 3 |
843 | << QtTestTableView::MovePrevious << Qt::NoModifier |
844 | << 0 << 2 << IntPair(0,0) << IntPair(0,0); |
845 | |
846 | QTest::newRow(dataTag: "MovePrevious (0,1)" ) |
847 | << 4 << 4 << -1 << -1 |
848 | << 0 << 1 |
849 | << QtTestTableView::MovePrevious << Qt::NoModifier |
850 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
851 | |
852 | QTest::newRow(dataTag: "MovePrevious, wrap (1,0)" ) |
853 | << 4 << 4 << -1 << -1 |
854 | << 1 << 0 |
855 | << QtTestTableView::MovePrevious << Qt::NoModifier |
856 | << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
857 | |
858 | QTest::newRow(dataTag: "MovePrevious, wrap, (0,0)" ) |
859 | << 4 << 4 << -1 << -1 |
860 | << 0 << 0 |
861 | << QtTestTableView::MovePrevious << Qt::NoModifier |
862 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
863 | |
864 | QTest::newRow(dataTag: "MovePrevious, hidden column 1 (0,2)" ) |
865 | << 4 << 4 << -1 << 1 |
866 | << 0 << 2 |
867 | << QtTestTableView::MovePrevious << Qt::NoModifier |
868 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
869 | |
870 | QTest::newRow(dataTag: "MovePrevious, wrap, hidden column 3 (0,2)" ) |
871 | << 4 << 4 << -1 << 3 |
872 | << 0 << 2 |
873 | << QtTestTableView::MovePrevious << Qt::NoModifier |
874 | << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
875 | |
876 | QTest::newRow(dataTag: "MovePrevious, wrapy, hidden column 0 (0,1)" ) |
877 | << 4 << 4 << -1 << 0 |
878 | << 0 << 1 |
879 | << QtTestTableView::MovePrevious << Qt::NoModifier |
880 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
881 | |
882 | QTest::newRow(dataTag: "MovePrevious, wrap, hidden column 0, hidden row 0 (1,1)" ) |
883 | << 4 << 4 << 0 << 0 |
884 | << 1 << 1 |
885 | << QtTestTableView::MovePrevious << Qt::NoModifier |
886 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
887 | |
888 | QTest::newRow(dataTag: "MovePrevious, wrap, hidden column 1, moved column from 0 to 3. (1,2)" ) |
889 | << 4 << 4 << -1 << 1 |
890 | << 1 << 2 |
891 | << QtTestTableView::MovePrevious << Qt::NoModifier |
892 | << 0 << 0 << IntPair(0,0) << IntPair(0,3); |
893 | |
894 | // MoveDown |
895 | QTest::newRow(dataTag: "MoveDown (0,0)" ) |
896 | << 4 << 4 << -1 << -1 |
897 | << 0 << 0 |
898 | << QtTestTableView::MoveDown << Qt::NoModifier |
899 | << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
900 | |
901 | QTest::newRow(dataTag: "MoveDown (3,0)" ) |
902 | << 4 << 4 << -1 << -1 |
903 | << 3 << 0 |
904 | << QtTestTableView::MoveDown << Qt::NoModifier |
905 | << 3 << 0 << IntPair(0,0) << IntPair(0,0); |
906 | |
907 | QTest::newRow(dataTag: "MoveDown (3,3)" ) |
908 | << 4 << 4 << -1 << -1 |
909 | << 3 << 3 |
910 | << QtTestTableView::MoveDown << Qt::NoModifier |
911 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
912 | |
913 | QTest::newRow(dataTag: "MoveDown, hidden row 1 (0,0)" ) |
914 | << 4 << 4 << 1 << -1 |
915 | << 0 << 0 |
916 | << QtTestTableView::MoveDown << Qt::NoModifier |
917 | << 2 << 0 << IntPair(0,0) << IntPair(0,0); |
918 | |
919 | QTest::newRow(dataTag: "MoveDown, hidden row 3 (2,0)" ) |
920 | << 4 << 4 << 3 << -1 |
921 | << 2 << 0 |
922 | << QtTestTableView::MoveDown << Qt::NoModifier |
923 | << 2 << 0 << IntPair(0,0) << IntPair(0,0); |
924 | |
925 | QTest::newRow(dataTag: "MoveDown, hidden row 0 hidden column 0 (0,0)" ) |
926 | << 4 << 4 << 0 << 0 |
927 | << 0 << 0 |
928 | << QtTestTableView::MoveDown << Qt::NoModifier |
929 | << 1 << 1 << IntPair(0,0) << IntPair(0,0); |
930 | |
931 | // MoveUp |
932 | QTest::newRow(dataTag: "MoveUp (0,0)" ) |
933 | << 4 << 4 << -1 << -1 |
934 | << 0 << 0 |
935 | << QtTestTableView::MoveUp << Qt::NoModifier |
936 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
937 | |
938 | QTest::newRow(dataTag: "MoveUp (3, 0)" ) |
939 | << 4 << 4 << -1 << -1 |
940 | << 3 << 0 |
941 | << QtTestTableView::MoveUp << Qt::NoModifier |
942 | << 2 << 0 << IntPair(0,0) << IntPair(0,0); |
943 | |
944 | QTest::newRow(dataTag: "MoveUp (0,1)" ) |
945 | << 4 << 4 << -1 << -1 |
946 | << 0 << 1 |
947 | << QtTestTableView::MoveUp << Qt::NoModifier |
948 | << 0 << 1 << IntPair(0,0) << IntPair(0,0); |
949 | |
950 | QTest::newRow(dataTag: "MoveUp, hidden row 1 (2,0)" ) |
951 | << 4 << 4 << 1 << -1 |
952 | << 2 << 0 |
953 | << QtTestTableView::MoveUp << Qt::NoModifier |
954 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
955 | |
956 | QTest::newRow(dataTag: "MoveUp, hidden row (1,0)" ) |
957 | << 4 << 4 << 0 << -1 |
958 | << 1 << 0 |
959 | << QtTestTableView::MoveUp << Qt::NoModifier |
960 | << 1 << 0 << IntPair(0,0) << IntPair(0,0); |
961 | |
962 | // MoveHome |
963 | QTest::newRow(dataTag: "MoveHome (0,0)" ) |
964 | << 4 << 4 << -1 << -1 |
965 | << 0 << 0 |
966 | << QtTestTableView::MoveHome << Qt::NoModifier |
967 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
968 | |
969 | QTest::newRow(dataTag: "MoveHome (3,3)" ) |
970 | << 4 << 4 << -1 << -1 |
971 | << 3 << 3 |
972 | << QtTestTableView::MoveHome << Qt::NoModifier |
973 | << 3 << 0 << IntPair(0,0) << IntPair(0,0); |
974 | |
975 | QTest::newRow(dataTag: "MoveHome, hidden column 0 (3,3)" ) |
976 | << 4 << 4 << -1 << 0 |
977 | << 3 << 3 |
978 | << QtTestTableView::MoveHome << Qt::NoModifier |
979 | << 3 << 1 << IntPair(0,0) << IntPair(0,0); |
980 | |
981 | // Use Ctrl modifier |
982 | QTest::newRow(dataTag: "MoveHome + Ctrl (0,0)" ) |
983 | << 4 << 4 << -1 << -1 |
984 | << 0 << 0 |
985 | << QtTestTableView::MoveHome << Qt::ControlModifier |
986 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
987 | |
988 | QTest::newRow(dataTag: "MoveHome + Ctrl (3,3)" ) |
989 | << 4 << 4 << -1 << -1 |
990 | << 3 << 3 |
991 | << QtTestTableView::MoveHome << Qt::ControlModifier |
992 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
993 | |
994 | QTest::newRow(dataTag: "MoveHome + Ctrl, hidden column 0, hidden row 0 (3,3)" ) |
995 | << 4 << 4 << 0 << 0 |
996 | << 3 << 3 |
997 | << QtTestTableView::MoveHome << Qt::ControlModifier |
998 | << 1 << 1 << IntPair(0,0) << IntPair(0,0); |
999 | |
1000 | // MoveEnd |
1001 | QTest::newRow(dataTag: "MoveEnd (0,0)" ) |
1002 | << 4 << 4 << -1 << -1 |
1003 | << 0 << 0 |
1004 | << QtTestTableView::MoveEnd << Qt::NoModifier |
1005 | << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
1006 | |
1007 | QTest::newRow(dataTag: "MoveEnd (3,3)" ) |
1008 | << 4 << 4 << -1 << -1 |
1009 | << 3 << 3 |
1010 | << QtTestTableView::MoveEnd << Qt::NoModifier |
1011 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
1012 | |
1013 | QTest::newRow(dataTag: "MoveEnd, hidden column (0,0)" ) |
1014 | << 4 << 4 << -1 << 3 |
1015 | << 0 << 0 |
1016 | << QtTestTableView::MoveEnd << Qt::NoModifier |
1017 | << 0<< 2 << IntPair(0,0) << IntPair(0,0); |
1018 | |
1019 | // Use Ctrl modifier |
1020 | QTest::newRow(dataTag: "MoveEnd + Ctrl (0,0)" ) |
1021 | << 4 << 4 << -1 << -1 |
1022 | << 0 << 0 |
1023 | << QtTestTableView::MoveEnd << Qt::ControlModifier |
1024 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
1025 | |
1026 | QTest::newRow(dataTag: "MoveEnd + Ctrl (3,3)" ) |
1027 | << 4 << 4 << -1 << -1 |
1028 | << 3 << 3 |
1029 | << QtTestTableView::MoveEnd << Qt::ControlModifier |
1030 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
1031 | |
1032 | QTest::newRow(dataTag: "MoveEnd + Ctrl, hidden column 3 (0,0)" ) |
1033 | << 4 << 4 << -1 << 3 |
1034 | << 0 << 0 |
1035 | << QtTestTableView::MoveEnd << Qt::ControlModifier |
1036 | << 3 << 2 << IntPair(0,0) << IntPair(0,0); |
1037 | |
1038 | QTest::newRow(dataTag: "MoveEnd + Ctrl, hidden column 3, hidden row 3 (0,0)" ) |
1039 | << 4 << 4 << 3 << 3 |
1040 | << 0 << 0 |
1041 | << QtTestTableView::MoveEnd << Qt::ControlModifier |
1042 | << 2 << 2 << IntPair(0,0) << IntPair(0,0); |
1043 | |
1044 | QTest::newRow(dataTag: "MovePageUp (0,0)" ) |
1045 | << 4 << 4 << -1 << -1 |
1046 | << 0 << 0 |
1047 | << QtTestTableView::MovePageUp << Qt::NoModifier |
1048 | << 0 << 0 << IntPair(0,0) << IntPair(0,0); |
1049 | |
1050 | QTest::newRow(dataTag: "MovePageUp (3,3)" ) |
1051 | << 4 << 4 << -1 << -1 |
1052 | << 3 << 3 |
1053 | << QtTestTableView::MovePageUp << Qt::NoModifier |
1054 | << 0 << 3 << IntPair(0,0) << IntPair(0,0); |
1055 | |
1056 | QTest::newRow(dataTag: "MovePageDown (3, 3)" ) |
1057 | << 4 << 4 << -1 << -1 |
1058 | << 3 << 3 |
1059 | << QtTestTableView::MovePageDown << Qt::NoModifier |
1060 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
1061 | |
1062 | QTest::newRow(dataTag: "MovePageDown (0, 3)" ) |
1063 | << 4 << 4 << -1 << -1 |
1064 | << 0 << 3 |
1065 | << QtTestTableView::MovePageDown << Qt::NoModifier |
1066 | << 3 << 3 << IntPair(0,0) << IntPair(0,0); |
1067 | } |
1068 | |
1069 | void tst_QTableView::moveCursor() |
1070 | { |
1071 | QFETCH(int, rowCount); |
1072 | QFETCH(int, columnCount); |
1073 | QFETCH(int, hideRow); |
1074 | QFETCH(int, hideColumn); |
1075 | QFETCH(int, startRow); |
1076 | QFETCH(int, startColumn); |
1077 | QFETCH(QtTestTableView::CursorAction, cursorMoveAction); |
1078 | QFETCH(Qt::KeyboardModifier, modifier); |
1079 | QFETCH(int, expectedRow); |
1080 | QFETCH(int, expectedColumn); |
1081 | QFETCH(IntPair, moveRow); |
1082 | QFETCH(IntPair, moveColumn); |
1083 | |
1084 | QtTestTableModel model(rowCount, columnCount); |
1085 | QtTestTableView view; |
1086 | |
1087 | view.setModel(&model); |
1088 | // we have to make sure that PgUp/PgDown can scroll to the bottom/top |
1089 | view.resize(w: view.horizontalHeader()->length() + 50, |
1090 | h: view.verticalHeader()->length() + 50); |
1091 | view.hideRow(row: hideRow); |
1092 | view.hideColumn(column: hideColumn); |
1093 | if (moveColumn.first != moveColumn.second) |
1094 | view.horizontalHeader()->moveSection(from: moveColumn.first, to: moveColumn.second); |
1095 | if (moveRow.first != moveRow.second) |
1096 | view.verticalHeader()->moveSection(from: moveRow.first, to: moveRow.second); |
1097 | |
1098 | view.show(); |
1099 | |
1100 | QModelIndex index = model.index(row: startRow, column: startColumn); |
1101 | view.setCurrentIndex(index); |
1102 | |
1103 | QModelIndex newIndex = view.moveCursor(cursorAction: cursorMoveAction, modifiers: modifier); |
1104 | // expected fails, task 119433 |
1105 | if(newIndex.row() == -1) |
1106 | return; |
1107 | QCOMPARE(newIndex.row(), expectedRow); |
1108 | QCOMPARE(newIndex.column(), expectedColumn); |
1109 | } |
1110 | |
1111 | void tst_QTableView::moveCursorStrikesBack_data() |
1112 | { |
1113 | QTest::addColumn<int>(name: "hideRow" ); |
1114 | QTest::addColumn<int>(name: "hideColumn" ); |
1115 | QTest::addColumn<IntList>(name: "disableRows" ); |
1116 | QTest::addColumn<IntList>(name: "disableColumns" ); |
1117 | QTest::addColumn<QRect>(name: "span" ); |
1118 | |
1119 | QTest::addColumn<int>(name: "startRow" ); |
1120 | QTest::addColumn<int>(name: "startColumn" ); |
1121 | QTest::addColumn<CursorActionList>(name: "cursorMoveActions" ); |
1122 | QTest::addColumn<int>(name: "expectedRow" ); |
1123 | QTest::addColumn<int>(name: "expectedColumn" ); |
1124 | |
1125 | QTest::newRow(dataTag: "Last column disabled. Task QTBUG-3878" ) << -1 << -1 |
1126 | << IntList() |
1127 | << (IntList() << 6) |
1128 | << QRect() |
1129 | << 0 << 5 |
1130 | << CursorActionList{QtTestTableView::MoveNext} |
1131 | << 1 << 0; |
1132 | |
1133 | QTest::newRow(dataTag: "Last column disabled 2. Task QTBUG-3878" ) << -1 << -1 |
1134 | << IntList() |
1135 | << (IntList() << 6) |
1136 | << QRect() |
1137 | << 1 << 0 |
1138 | << CursorActionList{QtTestTableView::MovePrevious} |
1139 | << 0 << 5; |
1140 | |
1141 | QTest::newRow(dataTag: "Span, anchor column hidden" ) << -1 << 1 |
1142 | << IntList() |
1143 | << IntList() |
1144 | << QRect(1, 2, 2, 3) |
1145 | << 2 << 0 |
1146 | << CursorActionList{QtTestTableView::MoveNext} |
1147 | << 2 << 1; |
1148 | |
1149 | QTest::newRow(dataTag: "Span, anchor column disabled" ) << -1 << -1 |
1150 | << IntList() |
1151 | << (IntList() << 1) |
1152 | << QRect(1, 2, 2, 3) |
1153 | << 2 << 0 |
1154 | << CursorActionList{QtTestTableView::MoveNext} |
1155 | << 2 << 1; |
1156 | |
1157 | QTest::newRow(dataTag: "Span, anchor row hidden" ) << 2 << -1 |
1158 | << IntList() |
1159 | << IntList() |
1160 | << QRect(1, 2, 2, 3) |
1161 | << 1 << 2 |
1162 | << CursorActionList{QtTestTableView::MoveDown} |
1163 | << 2 << 1; |
1164 | |
1165 | QTest::newRow(dataTag: "Span, anchor row disabled" ) << -1 << -1 |
1166 | << (IntList() << 2) |
1167 | << IntList() |
1168 | << QRect(1, 2, 2, 3) |
1169 | << 1 << 2 |
1170 | << CursorActionList{QtTestTableView::MoveDown} |
1171 | << 2 << 1; |
1172 | |
1173 | QTest::newRow(dataTag: "Move through span right" ) << -1 << -1 |
1174 | << IntList() |
1175 | << IntList() |
1176 | << QRect(1, 2, 2, 3) |
1177 | << 3 << 0 |
1178 | << CursorActionList{QtTestTableView::MoveRight, |
1179 | QtTestTableView::MoveRight} |
1180 | << 3 << 3; |
1181 | |
1182 | QTest::newRow(dataTag: "Move through span left" ) << -1 << -1 |
1183 | << IntList() |
1184 | << IntList() |
1185 | << QRect(1, 2, 2, 3) |
1186 | << 3 << 3 |
1187 | << CursorActionList{QtTestTableView::MoveLeft, |
1188 | QtTestTableView::MoveLeft} |
1189 | << 3 << 0; |
1190 | |
1191 | QTest::newRow(dataTag: "Move through span down" ) << -1 << -1 |
1192 | << IntList() |
1193 | << IntList() |
1194 | << QRect(1, 2, 2, 3) |
1195 | << 1 << 2 |
1196 | << CursorActionList{QtTestTableView::MoveDown, |
1197 | QtTestTableView::MoveDown} |
1198 | << 5 << 2; |
1199 | |
1200 | QTest::newRow(dataTag: "Move through span up" ) << -1 << -1 |
1201 | << IntList() |
1202 | << IntList() |
1203 | << QRect(1, 2, 2, 3) |
1204 | << 5 << 2 |
1205 | << CursorActionList{QtTestTableView::MoveUp, |
1206 | QtTestTableView::MoveUp} |
1207 | << 1 << 2; |
1208 | |
1209 | IntList fullList; |
1210 | for (int i = 0; i < 7; ++i) |
1211 | fullList << i; |
1212 | |
1213 | QTest::newRow(dataTag: "All disabled, wrap forward. => invalid index" ) << -1 << -1 |
1214 | << fullList |
1215 | << fullList |
1216 | << QRect() |
1217 | << 1 << 0 |
1218 | << CursorActionList{QtTestTableView::MoveNext} |
1219 | << -1 << -1; |
1220 | |
1221 | QTest::newRow(dataTag: "All disabled, wrap backwards. => invalid index" ) << -1 << -1 |
1222 | << fullList |
1223 | << fullList |
1224 | << QRect() |
1225 | << 1 << 0 |
1226 | << CursorActionList{QtTestTableView::MovePrevious} |
1227 | << -1 << -1; |
1228 | |
1229 | QTest::newRow(dataTag: "Last column disabled, MoveEnd. QTBUG-72400" ) << -1 << -1 |
1230 | << IntList() |
1231 | << (IntList() << 6) |
1232 | << QRect() |
1233 | << 0 << 0 |
1234 | << CursorActionList{QtTestTableView::MoveEnd} |
1235 | << 0 << 5; |
1236 | |
1237 | QTest::newRow(dataTag: "First column disabled, MoveHome. QTBUG-72400" ) << -1 << -1 |
1238 | << IntList() |
1239 | << (IntList() << 0) |
1240 | << QRect() |
1241 | << 0 << 6 |
1242 | << CursorActionList{QtTestTableView::MoveHome} |
1243 | << 0 << 1; |
1244 | |
1245 | QTest::newRow(dataTag: "First row disabled, MovePageUp. QTBUG-72400" ) << -1 << -1 |
1246 | << (IntList() << 0) |
1247 | << IntList() |
1248 | << QRect() |
1249 | << 2 << 0 |
1250 | << CursorActionList{QtTestTableView::MovePageUp} |
1251 | << 1 << 0; |
1252 | |
1253 | QTest::newRow(dataTag: "Last row disabled, MovePageDown. QTBUG-72400" ) << -1 << -1 |
1254 | << (IntList() << 6) |
1255 | << IntList() |
1256 | << QRect() |
1257 | << 4 << 0 |
1258 | << CursorActionList{QtTestTableView::MovePageDown} |
1259 | << 5 << 0; |
1260 | } |
1261 | |
1262 | void tst_QTableView::moveCursorStrikesBack() |
1263 | { |
1264 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
1265 | QSKIP("Wayland: This fails. Figure out why." ); |
1266 | |
1267 | QFETCH(int, hideRow); |
1268 | QFETCH(int, hideColumn); |
1269 | QFETCH(const IntList, disableRows); |
1270 | QFETCH(const IntList, disableColumns); |
1271 | QFETCH(QRect, span); |
1272 | |
1273 | QFETCH(int, startRow); |
1274 | QFETCH(int, startColumn); |
1275 | QFETCH(const CursorActionList, cursorMoveActions); |
1276 | QFETCH(int, expectedRow); |
1277 | QFETCH(int, expectedColumn); |
1278 | |
1279 | QtTestTableModel model(7, 7); |
1280 | QtTestTableView view; |
1281 | view.setModel(&model); |
1282 | view.hideRow(row: hideRow); |
1283 | view.hideColumn(column: hideColumn); |
1284 | |
1285 | if (span.height() && span.width()) |
1286 | view.setSpan(row: span.top(), column: span.left(), rowSpan: span.height(), columnSpan: span.width()); |
1287 | view.show(); |
1288 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
1289 | // resize to make sure there are scrollbars |
1290 | view.resize(w: view.columnWidth(column: 0) * 7, h: view.rowHeight(row: 0) * 7); |
1291 | |
1292 | QModelIndex index = model.index(row: startRow, column: startColumn); |
1293 | view.setCurrentIndex(index); |
1294 | |
1295 | for (int row : disableRows) |
1296 | model.disableRow(row); |
1297 | for (int column : disableColumns) |
1298 | model.disableColumn(column); |
1299 | |
1300 | int newRow = -1; |
1301 | int newColumn = -1; |
1302 | for (auto cursorMoveAction : cursorMoveActions) { |
1303 | QModelIndex newIndex = view.moveCursor(cursorAction: cursorMoveAction, modifiers: {}); |
1304 | view.setCurrentIndex(newIndex); |
1305 | newRow = newIndex.row(); |
1306 | newColumn = newIndex.column(); |
1307 | } |
1308 | |
1309 | QCOMPARE(newRow, expectedRow); |
1310 | QCOMPARE(newColumn, expectedColumn); |
1311 | } |
1312 | |
1313 | void tst_QTableView::moveCursorBiggerJump() |
1314 | { |
1315 | QtTestTableModel model(50, 7); |
1316 | QTableView view; |
1317 | view.setModel(&model); |
1318 | view.show(); |
1319 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
1320 | |
1321 | int height = view.horizontalHeader()->height(); |
1322 | for (int i=0;i<8;i++) |
1323 | height += view.verticalHeader()->sectionSize(logicalIndex: i); |
1324 | view.resize(w: view.width(), h: height); |
1325 | view.setCurrentIndex(model.index(row: 0,column: 0)); |
1326 | |
1327 | QTest::keyClick(widget: &view, key: Qt::Key_PageDown); |
1328 | QCOMPARE(view.indexAt(QPoint(0,0)), model.index(1,0)); |
1329 | QTest::keyClick(widget: &view, key: Qt::Key_PageDown); |
1330 | QCOMPARE(view.indexAt(QPoint(0,0)), model.index(8,0)); |
1331 | QTest::keyClick(widget: &view, key: Qt::Key_PageDown); |
1332 | QCOMPARE(view.indexAt(QPoint(0,0)), model.index(15,0)); |
1333 | QTest::keyClick(widget: &view, key: Qt::Key_PageUp); |
1334 | QCOMPARE(view.indexAt(QPoint(0,0)), model.index(14,0)); |
1335 | QTest::keyClick(widget: &view, key: Qt::Key_PageUp); |
1336 | QCOMPARE(view.indexAt(QPoint(0,0)), model.index(7,0)); |
1337 | QTest::keyClick(widget: &view, key: Qt::Key_PageUp); |
1338 | QCOMPARE(view.indexAt(QPoint(0,0)), model.index(0,0)); |
1339 | |
1340 | QTest::keyClick(widget: &view, key: Qt::Key_PageDown); |
1341 | view.verticalHeader()->hideSection(alogicalIndex: 0); |
1342 | QTest::keyClick(widget: &view, key: Qt::Key_PageUp); |
1343 | QTRY_COMPARE(view.currentIndex().row(), view.rowAt(0)); |
1344 | } |
1345 | |
1346 | void tst_QTableView::hideRows_data() |
1347 | { |
1348 | QTest::addColumn<int>(name: "rowCount" ); |
1349 | QTest::addColumn<int>(name: "columnCount" ); |
1350 | QTest::addColumn<int>(name: "showRow" ); // hide, then show |
1351 | QTest::addColumn<int>(name: "hideRow" ); // hide only |
1352 | QTest::addColumn<int>(name: "row" ); |
1353 | QTest::addColumn<int>(name: "column" ); |
1354 | QTest::addColumn<int>(name: "rowSpan" ); |
1355 | QTest::addColumn<int>(name: "columnSpan" ); |
1356 | |
1357 | QTest::newRow(dataTag: "show row 0, hide row 3, no span" ) |
1358 | << 10 << 10 |
1359 | << 0 |
1360 | << 3 |
1361 | << -1 << -1 |
1362 | << 1 << 1; |
1363 | |
1364 | QTest::newRow(dataTag: "show row 0, hide row 3, span" ) |
1365 | << 10 << 10 |
1366 | << 0 |
1367 | << 3 |
1368 | << 0 << 0 |
1369 | << 3 << 2; |
1370 | } |
1371 | |
1372 | void tst_QTableView::hideRows() |
1373 | { |
1374 | QFETCH(int, rowCount); |
1375 | QFETCH(int, columnCount); |
1376 | QFETCH(int, showRow); |
1377 | QFETCH(int, hideRow); |
1378 | QFETCH(int, row); |
1379 | QFETCH(int, column); |
1380 | QFETCH(int, rowSpan); |
1381 | QFETCH(int, columnSpan); |
1382 | |
1383 | QtTestTableModel model(rowCount, columnCount); |
1384 | QTableView view; |
1385 | |
1386 | view.setModel(&model); |
1387 | view.setSpan(row, column, rowSpan, columnSpan); |
1388 | |
1389 | view.hideRow(row: showRow); |
1390 | QVERIFY(view.isRowHidden(showRow)); |
1391 | |
1392 | view.hideRow(row: hideRow); |
1393 | QVERIFY(view.isRowHidden(hideRow)); |
1394 | |
1395 | view.showRow(row: showRow); |
1396 | QVERIFY(!view.isRowHidden(showRow)); |
1397 | QVERIFY(view.isRowHidden(hideRow)); |
1398 | } |
1399 | |
1400 | void tst_QTableView::hideColumns_data() |
1401 | { |
1402 | QTest::addColumn<int>(name: "rowCount" ); |
1403 | QTest::addColumn<int>(name: "columnCount" ); |
1404 | QTest::addColumn<int>(name: "showColumn" ); // hide, then show |
1405 | QTest::addColumn<int>(name: "hideColumn" ); // hide only |
1406 | QTest::addColumn<int>(name: "row" ); |
1407 | QTest::addColumn<int>(name: "column" ); |
1408 | QTest::addColumn<int>(name: "rowSpan" ); |
1409 | QTest::addColumn<int>(name: "columnSpan" ); |
1410 | |
1411 | QTest::newRow(dataTag: "show col 0, hide col 3, no span" ) |
1412 | << 10 << 10 |
1413 | << 0 |
1414 | << 3 |
1415 | << -1 << -1 |
1416 | << 1 << 1; |
1417 | |
1418 | QTest::newRow(dataTag: "show col 0, hide col 3, span" ) |
1419 | << 10 << 10 |
1420 | << 0 |
1421 | << 3 |
1422 | << 0 << 0 |
1423 | << 3 << 2; |
1424 | } |
1425 | |
1426 | void tst_QTableView::hideColumns() |
1427 | { |
1428 | QFETCH(int, rowCount); |
1429 | QFETCH(int, columnCount); |
1430 | QFETCH(int, showColumn); |
1431 | QFETCH(int, hideColumn); |
1432 | QFETCH(int, row); |
1433 | QFETCH(int, column); |
1434 | QFETCH(int, rowSpan); |
1435 | QFETCH(int, columnSpan); |
1436 | |
1437 | QtTestTableModel model(rowCount, columnCount); |
1438 | |
1439 | QTableView view; |
1440 | view.setModel(&model); |
1441 | view.setSpan(row, column, rowSpan, columnSpan); |
1442 | |
1443 | view.hideColumn(column: showColumn); |
1444 | QVERIFY(view.isColumnHidden(showColumn)); |
1445 | |
1446 | view.hideColumn(column: hideColumn); |
1447 | QVERIFY(view.isColumnHidden(hideColumn)); |
1448 | |
1449 | view.showColumn(column: showColumn); |
1450 | QVERIFY(!view.isColumnHidden(showColumn)); |
1451 | QVERIFY(view.isColumnHidden(hideColumn)); |
1452 | } |
1453 | |
1454 | void tst_QTableView::selection_data() |
1455 | { |
1456 | QTest::addColumn<int>(name: "rowCount" ); |
1457 | QTest::addColumn<int>(name: "columnCount" ); |
1458 | QTest::addColumn<int>(name: "row" ); |
1459 | QTest::addColumn<int>(name: "column" ); |
1460 | QTest::addColumn<int>(name: "rowSpan" ); |
1461 | QTest::addColumn<int>(name: "columnSpan" ); |
1462 | QTest::addColumn<int>(name: "hideRow" ); |
1463 | QTest::addColumn<int>(name: "hideColumn" ); |
1464 | QTest::addColumn<int>(name: "moveRowFrom" ); |
1465 | QTest::addColumn<int>(name: "moveRowTo" ); |
1466 | QTest::addColumn<int>(name: "moveColumnFrom" ); |
1467 | QTest::addColumn<int>(name: "moveColumnTo" ); |
1468 | QTest::addColumn<int>(name: "rowHeight" ); |
1469 | QTest::addColumn<int>(name: "columnWidth" ); |
1470 | QTest::addColumn<int>(name: "x" ); |
1471 | QTest::addColumn<int>(name: "y" ); |
1472 | QTest::addColumn<int>(name: "width" ); |
1473 | QTest::addColumn<int>(name: "height" ); |
1474 | QTest::addColumn<QItemSelectionModel::SelectionFlag>(name: "command" ); |
1475 | QTest::addColumn<int>(name: "selectedCount" ); // ### make this more detailed |
1476 | |
1477 | QTest::newRow(dataTag: "no span, no hidden, no moved, 3x3 select" ) |
1478 | << 10 << 10 // dim |
1479 | << -1 << -1 // pos |
1480 | << 1 << 1 // span |
1481 | << -1 << -1 // hide |
1482 | << -1 << -1 // move row |
1483 | << -1 << -1 // move col |
1484 | << 40 << 40 // cell size |
1485 | << 20 << 20 << 80 << 80 // rect |
1486 | << QItemSelectionModel::Select // command |
1487 | << 9; // selected count |
1488 | |
1489 | QTest::newRow(dataTag: "row span, no hidden, no moved, 3x3 select" ) |
1490 | << 10 << 10 // dim |
1491 | << 1 << 1 // pos |
1492 | << 2 << 1 // span |
1493 | << -1 << -1 // hide |
1494 | << -1 << -1 // move row |
1495 | << -1 << -1 // move col |
1496 | << 40 << 40 // cell size |
1497 | << 20 << 20 << 80 << 80 // rect |
1498 | << QItemSelectionModel::Select // command |
1499 | << 8; // selected count |
1500 | |
1501 | QTest::newRow(dataTag: "col span, no hidden, no moved, 3x3 select" ) |
1502 | << 10 << 10 // dim |
1503 | << 1 << 1 // pos |
1504 | << 1 << 2 // span |
1505 | << -1 << -1 // hide |
1506 | << -1 << -1 // move row |
1507 | << -1 << -1 // move col |
1508 | << 40 << 40 // cell size |
1509 | << 20 << 20 << 80 << 80 // rect |
1510 | << QItemSelectionModel::Select // command |
1511 | << 8; // selected count |
1512 | |
1513 | QTest::newRow(dataTag: "no span, row hidden, no moved, 3x3 select" ) |
1514 | << 10 << 10 // dim |
1515 | << -1 << -1 // pos |
1516 | << 1 << 1 // span |
1517 | << 1 << -1 // hide |
1518 | << -1 << -1 // move row |
1519 | << -1 << -1 // move col |
1520 | << 40 << 40 // cell size |
1521 | << 20 << 20 << 80 << 80 // rect |
1522 | << QItemSelectionModel::Select // command |
1523 | << 9; // selected count |
1524 | |
1525 | QTest::newRow(dataTag: "no span, col hidden, no moved, 3x3 select" ) |
1526 | << 10 << 10 // dim |
1527 | << -1 << -1 // pos |
1528 | << 1 << 1 // span |
1529 | << -1 << 1 // hide |
1530 | << -1 << -1 // move row |
1531 | << -1 << -1 // move col |
1532 | << 40 << 40 // cell size |
1533 | << 20 << 20 << 80 << 80 // rect |
1534 | << QItemSelectionModel::Select // command |
1535 | << 9; // selected count |
1536 | |
1537 | QTest::newRow(dataTag: "no span, no hidden, row moved, 3x3 select" ) |
1538 | << 10 << 10 // dim |
1539 | << -1 << -1 // pos |
1540 | << 1 << 1 // span |
1541 | << -1 << -1 // hide |
1542 | << 1 << 3 // move row |
1543 | << -1 << -1 // move col |
1544 | << 40 << 40 // cell size |
1545 | << 20 << 20 << 80 << 80 // rect |
1546 | << QItemSelectionModel::Select // command |
1547 | << 9; // selected count |
1548 | |
1549 | QTest::newRow(dataTag: "no span, no hidden, col moved, 3x3 select" ) |
1550 | << 10 << 10 // dim |
1551 | << -1 << -1 // pos |
1552 | << 1 << 1 // span |
1553 | << -1 << -1 // hide |
1554 | << -1 << -1 // move row |
1555 | << 1 << 3 // move col |
1556 | << 40 << 40 // cell size |
1557 | << 20 << 20 << 80 << 80 // rect |
1558 | << QItemSelectionModel::Select // command |
1559 | << 9; // selected count |
1560 | } |
1561 | |
1562 | void tst_QTableView::selection() |
1563 | { |
1564 | QFETCH(int, rowCount); |
1565 | QFETCH(int, columnCount); |
1566 | QFETCH(int, row); |
1567 | QFETCH(int, column); |
1568 | QFETCH(int, rowSpan); |
1569 | QFETCH(int, columnSpan); |
1570 | QFETCH(int, hideRow); |
1571 | QFETCH(int, hideColumn); |
1572 | QFETCH(int, moveRowFrom); |
1573 | QFETCH(int, moveRowTo); |
1574 | QFETCH(int, moveColumnFrom); |
1575 | QFETCH(int, moveColumnTo); |
1576 | QFETCH(int, rowHeight); |
1577 | QFETCH(int, columnWidth); |
1578 | QFETCH(int, x); |
1579 | QFETCH(int, y); |
1580 | QFETCH(int, width); |
1581 | QFETCH(int, height); |
1582 | QFETCH(QItemSelectionModel::SelectionFlag, command); |
1583 | QFETCH(int, selectedCount); |
1584 | |
1585 | QtTestTableModel model(rowCount, columnCount); |
1586 | |
1587 | QtTestTableView view; |
1588 | view.show(); |
1589 | view.setModel(&model); |
1590 | |
1591 | view.setSpan(row, column, rowSpan, columnSpan); |
1592 | |
1593 | view.hideRow(row: hideRow); |
1594 | view.hideColumn(column: hideColumn); |
1595 | |
1596 | view.verticalHeader()->moveSection(from: moveRowFrom, to: moveRowTo); |
1597 | view.horizontalHeader()->moveSection(from: moveColumnFrom, to: moveColumnTo); |
1598 | |
1599 | for (int r = 0; r < rowCount; ++r) |
1600 | view.setRowHeight(row: r, height: rowHeight); |
1601 | for (int c = 0; c < columnCount; ++c) |
1602 | view.setColumnWidth(column: c, width: columnWidth); |
1603 | |
1604 | view.setSelection(rect: QRect(x, y, width, height), command); |
1605 | |
1606 | QCOMPARE(view.selectedIndexes().count(), selectedCount); |
1607 | } |
1608 | |
1609 | void tst_QTableView::selectRow_data() |
1610 | { |
1611 | QTest::addColumn<int>(name: "rowCount" ); |
1612 | QTest::addColumn<int>(name: "columnCount" ); |
1613 | QTest::addColumn<int>(name: "row" ); |
1614 | QTest::addColumn<QAbstractItemView::SelectionMode>(name: "mode" ); |
1615 | QTest::addColumn<QAbstractItemView::SelectionBehavior>(name: "behavior" ); |
1616 | QTest::addColumn<int>(name: "selectedItems" ); |
1617 | |
1618 | QTest::newRow(dataTag: "SingleSelection and SelectItems" ) |
1619 | << 10 << 10 |
1620 | << 0 |
1621 | << QAbstractItemView::SingleSelection |
1622 | << QAbstractItemView::SelectItems |
1623 | << 0; |
1624 | |
1625 | QTest::newRow(dataTag: "SingleSelection and SelectRows" ) |
1626 | << 10 << 10 |
1627 | << 0 |
1628 | << QAbstractItemView::SingleSelection |
1629 | << QAbstractItemView::SelectRows |
1630 | << 10; |
1631 | |
1632 | QTest::newRow(dataTag: "SingleSelection and SelectColumns" ) |
1633 | << 10 << 10 |
1634 | << 0 |
1635 | << QAbstractItemView::SingleSelection |
1636 | << QAbstractItemView::SelectColumns |
1637 | << 0; |
1638 | |
1639 | QTest::newRow(dataTag: "MultiSelection and SelectItems" ) |
1640 | << 10 << 10 |
1641 | << 0 |
1642 | << QAbstractItemView::MultiSelection |
1643 | << QAbstractItemView::SelectItems |
1644 | << 10; |
1645 | |
1646 | QTest::newRow(dataTag: "MultiSelection and SelectRows" ) |
1647 | << 10 << 10 |
1648 | << 0 |
1649 | << QAbstractItemView::MultiSelection |
1650 | << QAbstractItemView::SelectRows |
1651 | << 10; |
1652 | |
1653 | QTest::newRow(dataTag: "MultiSelection and SelectColumns" ) |
1654 | << 10 << 10 |
1655 | << 0 |
1656 | << QAbstractItemView::MultiSelection |
1657 | << QAbstractItemView::SelectColumns |
1658 | << 0; |
1659 | |
1660 | QTest::newRow(dataTag: "ExtendedSelection and SelectItems" ) |
1661 | << 10 << 10 |
1662 | << 0 |
1663 | << QAbstractItemView::ExtendedSelection |
1664 | << QAbstractItemView::SelectItems |
1665 | << 10; |
1666 | |
1667 | QTest::newRow(dataTag: "ExtendedSelection and SelectRows" ) |
1668 | << 10 << 10 |
1669 | << 0 |
1670 | << QAbstractItemView::ExtendedSelection |
1671 | << QAbstractItemView::SelectRows |
1672 | << 10; |
1673 | |
1674 | QTest::newRow(dataTag: "ExtendedSelection and SelectColumns" ) |
1675 | << 10 << 10 |
1676 | << 0 |
1677 | << QAbstractItemView::ExtendedSelection |
1678 | << QAbstractItemView::SelectColumns |
1679 | << 0; |
1680 | |
1681 | QTest::newRow(dataTag: "ContiguousSelection and SelectItems" ) |
1682 | << 10 << 10 |
1683 | << 0 |
1684 | << QAbstractItemView::ContiguousSelection |
1685 | << QAbstractItemView::SelectItems |
1686 | << 10; |
1687 | |
1688 | QTest::newRow(dataTag: "ContiguousSelection and SelectRows" ) |
1689 | << 10 << 10 |
1690 | << 0 |
1691 | << QAbstractItemView::ContiguousSelection |
1692 | << QAbstractItemView::SelectRows |
1693 | << 10; |
1694 | |
1695 | QTest::newRow(dataTag: "ContiguousSelection and SelectColumns" ) |
1696 | << 10 << 10 |
1697 | << 0 |
1698 | << QAbstractItemView::ContiguousSelection |
1699 | << QAbstractItemView::SelectColumns |
1700 | << 0; |
1701 | } |
1702 | |
1703 | void tst_QTableView::selectRow() |
1704 | { |
1705 | QFETCH(int, rowCount); |
1706 | QFETCH(int, columnCount); |
1707 | QFETCH(int, row); |
1708 | QFETCH(QAbstractItemView::SelectionMode, mode); |
1709 | QFETCH(QAbstractItemView::SelectionBehavior, behavior); |
1710 | QFETCH(int, selectedItems); |
1711 | |
1712 | QtTestTableModel model(rowCount, columnCount); |
1713 | QTableView view; |
1714 | |
1715 | view.setModel(&model); |
1716 | view.setSelectionMode(mode); |
1717 | view.setSelectionBehavior(behavior); |
1718 | |
1719 | QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0); |
1720 | |
1721 | view.selectRow(row); |
1722 | |
1723 | //test we have 10 items selected |
1724 | QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems); |
1725 | //test that all 10 items are in the same row |
1726 | for (int i = 0; selectedItems > 0 && i < rowCount; ++i) |
1727 | QCOMPARE(view.selectionModel()->selectedIndexes().at(i).row(), row); |
1728 | } |
1729 | |
1730 | void tst_QTableView::selectColumn_data() |
1731 | { |
1732 | QTest::addColumn<int>(name: "rowCount" ); |
1733 | QTest::addColumn<int>(name: "columnCount" ); |
1734 | QTest::addColumn<int>(name: "column" ); |
1735 | QTest::addColumn<QAbstractItemView::SelectionMode>(name: "mode" ); |
1736 | QTest::addColumn<QAbstractItemView::SelectionBehavior>(name: "behavior" ); |
1737 | QTest::addColumn<int>(name: "selectedItems" ); |
1738 | |
1739 | QTest::newRow(dataTag: "SingleSelection and SelectItems" ) |
1740 | << 10 << 10 |
1741 | << 0 |
1742 | << QAbstractItemView::SingleSelection |
1743 | << QAbstractItemView::SelectItems |
1744 | << 0; |
1745 | |
1746 | QTest::newRow(dataTag: "SingleSelection and SelectRows" ) |
1747 | << 10 << 10 |
1748 | << 0 |
1749 | << QAbstractItemView::SingleSelection |
1750 | << QAbstractItemView::SelectRows |
1751 | << 0; |
1752 | |
1753 | QTest::newRow(dataTag: "SingleSelection and SelectColumns" ) |
1754 | << 10 << 10 |
1755 | << 0 |
1756 | << QAbstractItemView::SingleSelection |
1757 | << QAbstractItemView::SelectColumns |
1758 | << 10; |
1759 | |
1760 | QTest::newRow(dataTag: "MultiSelection and SelectItems" ) |
1761 | << 10 << 10 |
1762 | << 0 |
1763 | << QAbstractItemView::MultiSelection |
1764 | << QAbstractItemView::SelectItems |
1765 | << 10; |
1766 | |
1767 | QTest::newRow(dataTag: "MultiSelection and SelectRows" ) |
1768 | << 10 << 10 |
1769 | << 0 |
1770 | << QAbstractItemView::MultiSelection |
1771 | << QAbstractItemView::SelectRows |
1772 | << 0; |
1773 | |
1774 | QTest::newRow(dataTag: "MultiSelection and SelectColumns" ) |
1775 | << 10 << 10 |
1776 | << 0 |
1777 | << QAbstractItemView::MultiSelection |
1778 | << QAbstractItemView::SelectColumns |
1779 | << 10; |
1780 | |
1781 | QTest::newRow(dataTag: "ExtendedSelection and SelectItems" ) |
1782 | << 10 << 10 |
1783 | << 0 |
1784 | << QAbstractItemView::ExtendedSelection |
1785 | << QAbstractItemView::SelectItems |
1786 | << 10; |
1787 | |
1788 | QTest::newRow(dataTag: "ExtendedSelection and SelectRows" ) |
1789 | << 10 << 10 |
1790 | << 0 |
1791 | << QAbstractItemView::ExtendedSelection |
1792 | << QAbstractItemView::SelectRows |
1793 | << 0; |
1794 | |
1795 | QTest::newRow(dataTag: "ExtendedSelection and SelectColumns" ) |
1796 | << 10 << 10 |
1797 | << 0 |
1798 | << QAbstractItemView::ExtendedSelection |
1799 | << QAbstractItemView::SelectColumns |
1800 | << 10; |
1801 | |
1802 | QTest::newRow(dataTag: "ContiguousSelection and SelectItems" ) |
1803 | << 10 << 10 |
1804 | << 0 |
1805 | << QAbstractItemView::ContiguousSelection |
1806 | << QAbstractItemView::SelectItems |
1807 | << 10; |
1808 | |
1809 | QTest::newRow(dataTag: "ContiguousSelection and SelectRows" ) |
1810 | << 10 << 10 |
1811 | << 0 |
1812 | << QAbstractItemView::ContiguousSelection |
1813 | << QAbstractItemView::SelectRows |
1814 | << 0; |
1815 | |
1816 | QTest::newRow(dataTag: "ContiguousSelection and SelectColumns" ) |
1817 | << 10 << 10 |
1818 | << 0 |
1819 | << QAbstractItemView::ContiguousSelection |
1820 | << QAbstractItemView::SelectColumns |
1821 | << 10; |
1822 | } |
1823 | |
1824 | void tst_QTableView::selectColumn() |
1825 | { |
1826 | QFETCH(int, rowCount); |
1827 | QFETCH(int, columnCount); |
1828 | QFETCH(int, column); |
1829 | QFETCH(QAbstractItemView::SelectionMode, mode); |
1830 | QFETCH(QAbstractItemView::SelectionBehavior, behavior); |
1831 | QFETCH(int, selectedItems); |
1832 | |
1833 | QtTestTableModel model(rowCount, columnCount); |
1834 | |
1835 | QTableView view; |
1836 | view.setModel(&model); |
1837 | view.setSelectionMode(mode); |
1838 | view.setSelectionBehavior(behavior); |
1839 | |
1840 | QCOMPARE(view.selectionModel()->selectedIndexes().count(), 0); |
1841 | |
1842 | view.selectColumn(column); |
1843 | |
1844 | QCOMPARE(view.selectionModel()->selectedIndexes().count(), selectedItems); |
1845 | for (int i = 0; selectedItems > 0 && i < columnCount; ++i) |
1846 | QCOMPARE(view.selectionModel()->selectedIndexes().at(i).column(), column); |
1847 | } |
1848 | |
1849 | void tst_QTableView::selectall_data() |
1850 | { |
1851 | QTest::addColumn<int>(name: "rowCount" ); |
1852 | QTest::addColumn<int>(name: "columnCount" ); |
1853 | QTest::addColumn<int>(name: "row" ); |
1854 | QTest::addColumn<int>(name: "column" ); |
1855 | QTest::addColumn<int>(name: "rowSpan" ); |
1856 | QTest::addColumn<int>(name: "columnSpan" ); |
1857 | QTest::addColumn<int>(name: "hideRow" ); |
1858 | QTest::addColumn<int>(name: "hideColumn" ); |
1859 | QTest::addColumn<int>(name: "moveRowFrom" ); |
1860 | QTest::addColumn<int>(name: "moveRowTo" ); |
1861 | QTest::addColumn<int>(name: "moveColumnFrom" ); |
1862 | QTest::addColumn<int>(name: "moveColumnTo" ); |
1863 | QTest::addColumn<int>(name: "rowHeight" ); |
1864 | QTest::addColumn<int>(name: "columnWidth" ); |
1865 | QTest::addColumn<int>(name: "selectedCount" ); // ### make this more detailed |
1866 | |
1867 | QTest::newRow(dataTag: "no span, no hidden, no moved" ) |
1868 | << 10 << 10 // dim |
1869 | << -1 << -1 // pos |
1870 | << 1 << 1 // span |
1871 | << -1 << -1 // hide |
1872 | << -1 << -1 // move row |
1873 | << -1 << -1 // move col |
1874 | << 40 << 40 // cell size |
1875 | << 100; // selected count |
1876 | |
1877 | QTest::newRow(dataTag: "row span, no hidden, no moved" ) |
1878 | << 10 << 10 // dim |
1879 | << 1 << 1 // pos |
1880 | << 2 << 1 // span |
1881 | << -1 << -1 // hide |
1882 | << -1 << -1 // move row |
1883 | << -1 << -1 // move col |
1884 | << 40 << 40 // cell size |
1885 | << 99; // selected count |
1886 | |
1887 | QTest::newRow(dataTag: "col span, no hidden, no moved" ) |
1888 | << 10 << 10 // dim |
1889 | << 1 << 1 // pos |
1890 | << 1 << 2 // span |
1891 | << -1 << -1 // hide |
1892 | << -1 << -1 // move row |
1893 | << -1 << -1 // move col |
1894 | << 40 << 40 // cell size |
1895 | << 99; // selected count |
1896 | |
1897 | QTest::newRow(dataTag: "no span, row hidden, no moved" ) |
1898 | << 10 << 10 // dim |
1899 | << -1 << -1 // pos |
1900 | << 1 << 1 // span |
1901 | << 1 << -1 // hide |
1902 | << -1 << -1 // move row |
1903 | << -1 << -1 // move col |
1904 | << 40 << 40 // cell size |
1905 | << 90; // selected count |
1906 | |
1907 | QTest::newRow(dataTag: "no span, col hidden, no moved" ) |
1908 | << 10 << 10 // dim |
1909 | << -1 << -1 // pos |
1910 | << 1 << 1 // span |
1911 | << -1 << 1 // hide |
1912 | << -1 << -1 // move row |
1913 | << -1 << -1 // move col |
1914 | << 40 << 40 // cell size |
1915 | << 90; // selected count |
1916 | |
1917 | QTest::newRow(dataTag: "no span, no hidden, row moved" ) |
1918 | << 10 << 10 // dim |
1919 | << -1 << -1 // pos |
1920 | << 1 << 1 // span |
1921 | << -1 << -1 // hide |
1922 | << 1 << 3 // move row |
1923 | << -1 << -1 // move col |
1924 | << 40 << 40 // cell size |
1925 | << 100; // selected count |
1926 | |
1927 | QTest::newRow(dataTag: "no span, no hidden, col moved" ) |
1928 | << 10 << 10 // dim |
1929 | << -1 << -1 // pos |
1930 | << 1 << 1 // span |
1931 | << -1 << -1 // hide |
1932 | << -1 << -1 // move row |
1933 | << 1 << 3 // move col |
1934 | << 40 << 40 // cell size |
1935 | << 100; // selected count |
1936 | } |
1937 | |
1938 | void QTest__keySequence(QWidget* widget, const QKeySequence &ks) |
1939 | { |
1940 | for (int i = 0; i < ks.count(); ++i) |
1941 | { |
1942 | Qt::Key key = Qt::Key(ks[i] & ~Qt::KeyboardModifierMask); |
1943 | Qt::KeyboardModifiers modifiers = Qt::KeyboardModifiers(ks[i] & Qt::KeyboardModifierMask); |
1944 | QTest::keyClick(widget, key, modifier: modifiers); |
1945 | } |
1946 | } |
1947 | |
1948 | void tst_QTableView::selectall() |
1949 | { |
1950 | QFETCH(int, rowCount); |
1951 | QFETCH(int, columnCount); |
1952 | QFETCH(int, row); |
1953 | QFETCH(int, column); |
1954 | QFETCH(int, rowSpan); |
1955 | QFETCH(int, columnSpan); |
1956 | QFETCH(int, hideRow); |
1957 | QFETCH(int, hideColumn); |
1958 | QFETCH(int, moveRowFrom); |
1959 | QFETCH(int, moveRowTo); |
1960 | QFETCH(int, moveColumnFrom); |
1961 | QFETCH(int, moveColumnTo); |
1962 | QFETCH(int, rowHeight); |
1963 | QFETCH(int, columnWidth); |
1964 | QFETCH(int, selectedCount); |
1965 | |
1966 | QtTestTableModel model(rowCount, columnCount); |
1967 | |
1968 | QtTestTableView view; |
1969 | view.show(); |
1970 | view.setModel(&model); |
1971 | |
1972 | view.setSpan(row, column, rowSpan, columnSpan); |
1973 | |
1974 | view.hideRow(row: hideRow); |
1975 | view.hideColumn(column: hideColumn); |
1976 | |
1977 | view.verticalHeader()->moveSection(from: moveRowFrom, to: moveRowTo); |
1978 | view.horizontalHeader()->moveSection(from: moveColumnFrom, to: moveColumnTo); |
1979 | |
1980 | for (int r = 0; r < rowCount; ++r) |
1981 | view.setRowHeight(row: r, height: rowHeight); |
1982 | for (int c = 0; c < columnCount; ++c) |
1983 | view.setColumnWidth(column: c, width: columnWidth); |
1984 | |
1985 | // try slot first |
1986 | view.clearSelection(); |
1987 | QCOMPARE(view.selectedIndexes().count(), 0); |
1988 | view.selectAll(); |
1989 | QCOMPARE(view.selectedIndexes().count(), selectedCount); |
1990 | |
1991 | // try by key sequence |
1992 | view.clearSelection(); |
1993 | QCOMPARE(view.selectedIndexes().count(), 0); |
1994 | QTest__keySequence(widget: &view, ks: QKeySequence(QKeySequence::SelectAll)); |
1995 | QCOMPARE(view.selectedIndexes().count(), selectedCount); |
1996 | |
1997 | // check again with no selection mode |
1998 | view.clearSelection(); |
1999 | view.setSelectionMode(QAbstractItemView::NoSelection); |
2000 | QCOMPARE(view.selectedIndexes().count(), 0); |
2001 | QTest__keySequence(widget: &view, ks: QKeySequence(QKeySequence::SelectAll)); |
2002 | QCOMPARE(view.selectedIndexes().count(), 0); |
2003 | } |
2004 | |
2005 | void tst_QTableView::visualRect_data() |
2006 | { |
2007 | QTest::addColumn<int>(name: "rowCount" ); |
2008 | QTest::addColumn<int>(name: "columnCount" ); |
2009 | QTest::addColumn<int>(name: "hideRow" ); |
2010 | QTest::addColumn<int>(name: "hideColumn" ); |
2011 | QTest::addColumn<int>(name: "row" ); |
2012 | QTest::addColumn<int>(name: "column" ); |
2013 | QTest::addColumn<int>(name: "rowHeight" ); |
2014 | QTest::addColumn<int>(name: "columnWidth" ); |
2015 | QTest::addColumn<QRect>(name: "expectedRect" ); |
2016 | |
2017 | QTest::newRow(dataTag: "(0,0)" ) |
2018 | << 10 << 10 |
2019 | << -1 << -1 |
2020 | << 0 << 0 |
2021 | << 20 << 30 |
2022 | << QRect(0, 0, 29, 19); |
2023 | |
2024 | QTest::newRow(dataTag: "(0,0) hidden row" ) |
2025 | << 10 << 10 |
2026 | << 0 << -1 |
2027 | << 0 << 0 |
2028 | << 20 << 30 |
2029 | << QRect(); |
2030 | |
2031 | QTest::newRow(dataTag: "(0,0) hidden column" ) |
2032 | << 10 << 10 |
2033 | << -1 << 0 |
2034 | << 0 << 0 |
2035 | << 20 << 30 |
2036 | << QRect(); |
2037 | |
2038 | QTest::newRow(dataTag: "(0,0) hidden row and column" ) |
2039 | << 10 << 10 |
2040 | << 0 << 0 |
2041 | << 0 << 0 |
2042 | << 20 << 30 |
2043 | << QRect(); |
2044 | |
2045 | QTest::newRow(dataTag: "(0,0) out of bounds" ) |
2046 | << 10 << 10 |
2047 | << -1 << -1 |
2048 | << 20 << 20 |
2049 | << 20 << 30 |
2050 | << QRect(); |
2051 | |
2052 | QTest::newRow(dataTag: "(5,5), hidden row" ) |
2053 | << 10 << 10 |
2054 | << 5 << -1 |
2055 | << 5 << 5 |
2056 | << 20 << 30 |
2057 | << QRect(); |
2058 | |
2059 | QTest::newRow(dataTag: "(9,9)" ) |
2060 | << 10 << 10 |
2061 | << -1 << -1 |
2062 | << 9 << 9 |
2063 | << 20 << 30 |
2064 | << QRect(30*9, 20*9, 29, 19); |
2065 | } |
2066 | |
2067 | void tst_QTableView::visualRect() |
2068 | { |
2069 | QFETCH(int, rowCount); |
2070 | QFETCH(int, columnCount); |
2071 | QFETCH(int, hideRow); |
2072 | QFETCH(int, hideColumn); |
2073 | QFETCH(int, row); |
2074 | QFETCH(int, column); |
2075 | QFETCH(int, rowHeight); |
2076 | QFETCH(int, columnWidth); |
2077 | QFETCH(QRect, expectedRect); |
2078 | |
2079 | QtTestTableModel model(rowCount, columnCount); |
2080 | |
2081 | QTableView view; |
2082 | view.setModel(&model); |
2083 | view.horizontalHeader()->setMinimumSectionSize(0); |
2084 | view.verticalHeader()->setMinimumSectionSize(0); |
2085 | // Make sure that it has 1 pixel between each cell. |
2086 | view.setGridStyle(Qt::SolidLine); |
2087 | for (int i = 0; i < view.verticalHeader()->count(); ++i) |
2088 | view.verticalHeader()->resizeSection(logicalIndex: i, size: rowHeight); |
2089 | for (int i = 0; i < view.horizontalHeader()->count(); ++i) |
2090 | view.horizontalHeader()->resizeSection(logicalIndex: i, size: columnWidth); |
2091 | |
2092 | view.hideRow(row: hideRow); |
2093 | view.hideColumn(column: hideColumn); |
2094 | |
2095 | QRect rect = view.visualRect(index: model.index(row, column)); |
2096 | QCOMPARE(rect, expectedRect); |
2097 | } |
2098 | |
2099 | void tst_QTableView::fetchMore() |
2100 | { |
2101 | QtTestTableModel model(64, 64); |
2102 | |
2103 | model.can_fetch_more = true; |
2104 | |
2105 | QTableView view; |
2106 | view.setModel(&model); |
2107 | view.show(); |
2108 | |
2109 | QCOMPARE(model.fetch_more_count, 0); |
2110 | view.verticalScrollBar()->setValue(view.verticalScrollBar()->maximum()); |
2111 | QVERIFY(model.fetch_more_count > 0); |
2112 | |
2113 | model.fetch_more_count = 0; //reset |
2114 | view.scrollToTop(); |
2115 | QCOMPARE(model.fetch_more_count, 0); |
2116 | |
2117 | view.scrollToBottom(); |
2118 | QVERIFY(model.fetch_more_count > 0); |
2119 | |
2120 | model.fetch_more_count = 0; //reset |
2121 | view.scrollToTop(); |
2122 | view.setCurrentIndex(model.index(row: 0, column: 0)); |
2123 | QCOMPARE(model.fetch_more_count, 0); |
2124 | |
2125 | for (int i = 0; i < 64; ++i) |
2126 | QTest::keyClick(widget: &view, key: Qt::Key_Down); |
2127 | QCOMPARE(view.currentIndex(), model.index(63, 0)); |
2128 | QVERIFY(model.fetch_more_count > 0); |
2129 | } |
2130 | |
2131 | void tst_QTableView::() |
2132 | { |
2133 | QTableView view; |
2134 | |
2135 | // Make sure we don't delete ourselves |
2136 | view.setVerticalHeader(view.verticalHeader()); |
2137 | view.verticalHeader()->count(); |
2138 | view.setHorizontalHeader(view.horizontalHeader()); |
2139 | view.horizontalHeader()->count(); |
2140 | |
2141 | // Try passing around a header without it being deleted |
2142 | QTableView view2; |
2143 | view2.setVerticalHeader(view.verticalHeader()); |
2144 | view2.setHorizontalHeader(view.horizontalHeader()); |
2145 | view.setHorizontalHeader(new QHeaderView(Qt::Horizontal)); |
2146 | view.setVerticalHeader(new QHeaderView(Qt::Vertical)); |
2147 | view2.verticalHeader()->count(); |
2148 | view2.horizontalHeader()->count(); |
2149 | |
2150 | } |
2151 | |
2152 | void tst_QTableView::resizeRowsToContents_data() |
2153 | { |
2154 | QTest::addColumn<int>(name: "rowCount" ); |
2155 | QTest::addColumn<int>(name: "columnCount" ); |
2156 | QTest::addColumn<bool>(name: "showGrid" ); |
2157 | QTest::addColumn<int>(name: "cellWidth" ); |
2158 | QTest::addColumn<int>(name: "cellHeight" ); |
2159 | QTest::addColumn<int>(name: "rowHeight" ); |
2160 | QTest::addColumn<int>(name: "columnWidth" ); |
2161 | |
2162 | QTest::newRow(dataTag: "10x10 grid shown 40x40" ) |
2163 | << 10 << 10 << false << 40 << 40 << 40 << 40; |
2164 | |
2165 | QTest::newRow(dataTag: "10x10 grid not shown 40x40" ) |
2166 | << 10 << 10 << true << 40 << 40 << 41 << 41; |
2167 | } |
2168 | |
2169 | void tst_QTableView::resizeRowsToContents() |
2170 | { |
2171 | QFETCH(int, rowCount); |
2172 | QFETCH(int, columnCount); |
2173 | QFETCH(bool, showGrid); |
2174 | QFETCH(int, cellWidth); |
2175 | QFETCH(int, cellHeight); |
2176 | QFETCH(int, rowHeight); |
2177 | QFETCH(int, columnWidth); |
2178 | Q_UNUSED(columnWidth) |
2179 | |
2180 | QtTestTableModel model(rowCount, columnCount); |
2181 | QtTestTableView view; |
2182 | QtTestItemDelegate delegate; |
2183 | |
2184 | view.setModel(&model); |
2185 | view.setItemDelegate(&delegate); |
2186 | view.setShowGrid(showGrid); // the grid will add to the row height |
2187 | |
2188 | delegate.hint = QSize(cellWidth, cellHeight); |
2189 | |
2190 | QSignalSpy resizedSpy(view.verticalHeader(), &QHeaderView::sectionResized); |
2191 | view.resizeRowsToContents(); |
2192 | |
2193 | QCOMPARE(resizedSpy.count(), model.rowCount()); |
2194 | for (int r = 0; r < model.rowCount(); ++r) |
2195 | QCOMPARE(view.rowHeight(r), rowHeight); |
2196 | } |
2197 | |
2198 | void tst_QTableView::resizeColumnsToContents_data() |
2199 | { |
2200 | QTest::addColumn<int>(name: "rowCount" ); |
2201 | QTest::addColumn<int>(name: "columnCount" ); |
2202 | QTest::addColumn<bool>(name: "showGrid" ); |
2203 | QTest::addColumn<int>(name: "cellWidth" ); |
2204 | QTest::addColumn<int>(name: "cellHeight" ); |
2205 | QTest::addColumn<int>(name: "rowHeight" ); |
2206 | QTest::addColumn<int>(name: "columnWidth" ); |
2207 | |
2208 | QTest::newRow(dataTag: "10x10 grid not shown 60x60" ) |
2209 | << 10 << 10 << false << 60 << 60 << 60 << 60; |
2210 | |
2211 | QTest::newRow(dataTag: "10x10 grid shown 60x60" ) |
2212 | << 10 << 10 << true << 60 << 60 << 61 << 61; |
2213 | } |
2214 | |
2215 | void tst_QTableView::resizeColumnsToContents() |
2216 | { |
2217 | QFETCH(int, rowCount); |
2218 | QFETCH(int, columnCount); |
2219 | QFETCH(bool, showGrid); |
2220 | QFETCH(int, cellWidth); |
2221 | QFETCH(int, cellHeight); |
2222 | QFETCH(int, rowHeight); |
2223 | QFETCH(int, columnWidth); |
2224 | Q_UNUSED(rowHeight) |
2225 | |
2226 | QtTestTableModel model(rowCount, columnCount); |
2227 | QtTestTableView view; |
2228 | QtTestItemDelegate delegate; |
2229 | |
2230 | view.setModel(&model); |
2231 | view.setItemDelegate(&delegate); |
2232 | view.setShowGrid(showGrid); // the grid will add to the row height |
2233 | |
2234 | delegate.hint = QSize(cellWidth, cellHeight); |
2235 | |
2236 | QSignalSpy resizedSpy(view.horizontalHeader(), &QHeaderView::sectionResized); |
2237 | view.resizeColumnsToContents(); |
2238 | |
2239 | QCOMPARE(resizedSpy.count(), model.columnCount()); |
2240 | for (int c = 0; c < model.columnCount(); ++c) |
2241 | QCOMPARE(view.columnWidth(c), columnWidth); |
2242 | } |
2243 | |
2244 | void tst_QTableView::rowViewportPosition_data() |
2245 | { |
2246 | QTest::addColumn<int>(name: "rowCount" ); |
2247 | QTest::addColumn<int>(name: "rowHeight" ); |
2248 | QTest::addColumn<int>(name: "row" ); |
2249 | QTest::addColumn<QAbstractItemView::ScrollMode>(name: "verticalScrollMode" ); |
2250 | QTest::addColumn<int>(name: "verticalScrollValue" ); |
2251 | QTest::addColumn<int>(name: "rowViewportPosition" ); |
2252 | |
2253 | QTest::newRow(dataTag: "row 0, scroll per item 0" ) |
2254 | << 10 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0; |
2255 | |
2256 | QTest::newRow(dataTag: "row 1, scroll per item, 0" ) |
2257 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40; |
2258 | |
2259 | QTest::newRow(dataTag: "row 1, scroll per item, 1" ) |
2260 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0; |
2261 | |
2262 | QTest::newRow(dataTag: "row 5, scroll per item, 0" ) |
2263 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40; |
2264 | |
2265 | QTest::newRow(dataTag: "row 5, scroll per item, 5" ) |
2266 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0; |
2267 | |
2268 | QTest::newRow(dataTag: "row 9, scroll per item, 0" ) |
2269 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40; |
2270 | |
2271 | QTest::newRow(dataTag: "row 9, scroll per item, 5" ) |
2272 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40; |
2273 | |
2274 | QTest::newRow(dataTag: "row 0, scroll per pixel 0" ) |
2275 | << 10 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0; |
2276 | |
2277 | QTest::newRow(dataTag: "row 1, scroll per pixel, 0" ) |
2278 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40; |
2279 | |
2280 | QTest::newRow(dataTag: "row 1, scroll per pixel, 1" ) |
2281 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0; |
2282 | |
2283 | QTest::newRow(dataTag: "row 5, scroll per pixel, 0" ) |
2284 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40; |
2285 | |
2286 | QTest::newRow(dataTag: "row 5, scroll per pixel, 5" ) |
2287 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0; |
2288 | |
2289 | QTest::newRow(dataTag: "row 9, scroll per pixel, 0" ) |
2290 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40; |
2291 | |
2292 | QTest::newRow(dataTag: "row 9, scroll per pixel, 5" ) |
2293 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40; |
2294 | } |
2295 | |
2296 | void tst_QTableView::rowViewportPosition() |
2297 | { |
2298 | QFETCH(int, rowCount); |
2299 | QFETCH(int, rowHeight); |
2300 | QFETCH(int, row); |
2301 | QFETCH(QAbstractItemView::ScrollMode, verticalScrollMode); |
2302 | QFETCH(int, verticalScrollValue); |
2303 | QFETCH(int, rowViewportPosition); |
2304 | |
2305 | QtTestTableModel model(rowCount, 1); |
2306 | QtTestTableView view; |
2307 | setFrameless(&view); |
2308 | view.resize(w: 100, h: 2 * rowHeight); |
2309 | view.show(); |
2310 | |
2311 | view.setModel(&model); |
2312 | for (int r = 0; r < rowCount; ++r) |
2313 | view.setRowHeight(row: r, height: rowHeight); |
2314 | |
2315 | view.setVerticalScrollMode(verticalScrollMode); |
2316 | view.verticalScrollBar()->setValue(verticalScrollValue); |
2317 | |
2318 | #ifdef Q_OS_WINRT |
2319 | QEXPECT_FAIL("row 1, scroll per item, 1" , "Fails on WinRT - QTBUG-68297" , Abort); |
2320 | QEXPECT_FAIL("row 5, scroll per item, 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2321 | QEXPECT_FAIL("row 9, scroll per item, 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2322 | QEXPECT_FAIL("row 1, scroll per pixel, 1" , "Fails on WinRT - QTBUG-68297" , Abort); |
2323 | QEXPECT_FAIL("row 5, scroll per pixel, 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2324 | QEXPECT_FAIL("row 9, scroll per pixel, 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2325 | #endif |
2326 | QCOMPARE(view.rowViewportPosition(row), rowViewportPosition); |
2327 | } |
2328 | |
2329 | void tst_QTableView::rowAt_data() |
2330 | { |
2331 | QTest::addColumn<int>(name: "rowCount" ); |
2332 | QTest::addColumn<int>(name: "rowHeight" ); |
2333 | QTest::addColumn<IntList>(name: "hiddenRows" ); |
2334 | QTest::addColumn<int>(name: "coordinate" ); |
2335 | QTest::addColumn<int>(name: "row" ); |
2336 | |
2337 | QTest::newRow(dataTag: "row at 100" ) << 5 << 40 << IntList() << 100 << 2; |
2338 | QTest::newRow(dataTag: "row at 180" ) << 5 << 40 << IntList() << 180 << 4; |
2339 | QTest::newRow(dataTag: "row at 20" ) << 5 << 40 << IntList() << 20 << 0; |
2340 | |
2341 | // ### expand the dataset to include hidden rows |
2342 | } |
2343 | |
2344 | void tst_QTableView::rowAt() |
2345 | { |
2346 | QFETCH(int, rowCount); |
2347 | QFETCH(int, rowHeight); |
2348 | QFETCH(IntList, hiddenRows); |
2349 | QFETCH(int, coordinate); |
2350 | QFETCH(int, row); |
2351 | |
2352 | QtTestTableModel model(rowCount, 1); |
2353 | QtTestTableView view; |
2354 | view.resize(w: 100, h: 2 * rowHeight); |
2355 | |
2356 | view.setModel(&model); |
2357 | |
2358 | for (int r = 0; r < rowCount; ++r) |
2359 | view.setRowHeight(row: r, height: rowHeight); |
2360 | |
2361 | for (int i = 0; i < hiddenRows.count(); ++i) |
2362 | view.hideRow(row: hiddenRows.at(i)); |
2363 | |
2364 | QCOMPARE(view.rowAt(coordinate), row); |
2365 | } |
2366 | |
2367 | void tst_QTableView::rowHeight_data() |
2368 | { |
2369 | QTest::addColumn<int>(name: "rowCount" ); |
2370 | QTest::addColumn<IntList>(name: "rowHeights" ); |
2371 | QTest::addColumn<BoolList>(name: "hiddenRows" ); |
2372 | |
2373 | QTest::newRow(dataTag: "increasing" ) |
2374 | << 5 |
2375 | << (IntList() << 20 << 30 << 40 << 50 << 60) |
2376 | << (BoolList() << false << false << false << false << false); |
2377 | |
2378 | QTest::newRow(dataTag: "decreasing" ) |
2379 | << 5 |
2380 | << (IntList() << 60 << 50 << 40 << 30 << 20) |
2381 | << (BoolList() << false << false << false << false << false); |
2382 | |
2383 | QTest::newRow(dataTag: "random" ) |
2384 | << 5 |
2385 | << (IntList() << 87 << 34 << 68 << 91 << 27) |
2386 | << (BoolList() << false << false << false << false << false); |
2387 | |
2388 | // ### expand the dataset to include hidden rows |
2389 | } |
2390 | |
2391 | void tst_QTableView::rowHeight() |
2392 | { |
2393 | QFETCH(int, rowCount); |
2394 | QFETCH(IntList, rowHeights); |
2395 | QFETCH(BoolList, hiddenRows); |
2396 | |
2397 | QtTestTableModel model(rowCount, 1); |
2398 | QtTestTableView view; |
2399 | |
2400 | view.setModel(&model); |
2401 | |
2402 | for (int r = 0; r < rowCount; ++r) { |
2403 | view.setRowHeight(row: r, height: rowHeights.at(i: r)); |
2404 | view.setRowHidden(row: r, hide: hiddenRows.at(i: r)); |
2405 | } |
2406 | |
2407 | for (int r = 0; r < rowCount; ++r) { |
2408 | if (hiddenRows.at(i: r)) |
2409 | QCOMPARE(view.rowHeight(r), 0); |
2410 | else |
2411 | QCOMPARE(view.rowHeight(r), rowHeights.at(r)); |
2412 | } |
2413 | } |
2414 | |
2415 | void tst_QTableView::columnViewportPosition_data() |
2416 | { |
2417 | QTest::addColumn<int>(name: "columnCount" ); |
2418 | QTest::addColumn<int>(name: "columnWidth" ); |
2419 | QTest::addColumn<int>(name: "column" ); |
2420 | QTest::addColumn<QAbstractItemView::ScrollMode>(name: "horizontalScrollMode" ); |
2421 | QTest::addColumn<int>(name: "horizontalScrollValue" ); |
2422 | QTest::addColumn<int>(name: "columnViewportPosition" ); |
2423 | |
2424 | QTest::newRow(dataTag: "column 0, scroll per item 0" ) |
2425 | << 10 << 40 << 0 << QAbstractItemView::ScrollPerItem << 0 << 0; |
2426 | |
2427 | QTest::newRow(dataTag: "column 1, scroll per item, 0" ) |
2428 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 0 << 1 * 40; |
2429 | |
2430 | QTest::newRow(dataTag: "column 1, scroll per item, 1" ) |
2431 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerItem << 1 << 0; |
2432 | |
2433 | QTest::newRow(dataTag: "column 5, scroll per item, 0" ) |
2434 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 0 << 5 * 40; |
2435 | |
2436 | QTest::newRow(dataTag: "column 5, scroll per item, 5" ) |
2437 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerItem << 5 << 0; |
2438 | |
2439 | QTest::newRow(dataTag: "column 9, scroll per item, 0" ) |
2440 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 0 << 9 * 40; |
2441 | |
2442 | QTest::newRow(dataTag: "column 9, scroll per item, 5" ) |
2443 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerItem << 5 << 4 * 40; |
2444 | |
2445 | QTest::newRow(dataTag: "column 0, scroll per pixel 0" ) |
2446 | << 10 << 40 << 0 << QAbstractItemView::ScrollPerPixel << 0 << 0; |
2447 | |
2448 | QTest::newRow(dataTag: "column 1, scroll per pixel 0" ) |
2449 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 0 << 1 * 40; |
2450 | |
2451 | QTest::newRow(dataTag: "column 1, scroll per pixel 1" ) |
2452 | << 10 << 40 << 1 << QAbstractItemView::ScrollPerPixel << 1 * 40 << 0; |
2453 | |
2454 | QTest::newRow(dataTag: "column 5, scroll per pixel 0" ) |
2455 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 0 << 5 * 40; |
2456 | |
2457 | QTest::newRow(dataTag: "column 5, scroll per pixel 5" ) |
2458 | << 10 << 40 << 5 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 0; |
2459 | |
2460 | QTest::newRow(dataTag: "column 9, scroll per pixel 0" ) |
2461 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 0 << 9 * 40; |
2462 | |
2463 | QTest::newRow(dataTag: "column 9, scroll per pixel 5" ) |
2464 | << 10 << 40 << 9 << QAbstractItemView::ScrollPerPixel << 5 * 40 << 4 * 40; |
2465 | } |
2466 | |
2467 | void tst_QTableView::columnViewportPosition() |
2468 | { |
2469 | QFETCH(int, columnCount); |
2470 | QFETCH(int, columnWidth); |
2471 | QFETCH(int, column); |
2472 | QFETCH(QAbstractItemView::ScrollMode, horizontalScrollMode); |
2473 | QFETCH(int, horizontalScrollValue); |
2474 | QFETCH(int, columnViewportPosition); |
2475 | |
2476 | QtTestTableModel model(1, columnCount); |
2477 | QtTestTableView view; |
2478 | setFrameless(&view); |
2479 | view.resize(w: 2 * columnWidth, h: 100); |
2480 | view.show(); |
2481 | |
2482 | view.setModel(&model); |
2483 | for (int c = 0; c < columnCount; ++c) |
2484 | view.setColumnWidth(column: c, width: columnWidth); |
2485 | |
2486 | view.setHorizontalScrollMode(horizontalScrollMode); |
2487 | view.horizontalScrollBar()->setValue(horizontalScrollValue); |
2488 | |
2489 | #ifdef Q_OS_WINRT |
2490 | QEXPECT_FAIL("column 5, scroll per item, 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2491 | QEXPECT_FAIL("column 9, scroll per item, 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2492 | QEXPECT_FAIL("column 1, scroll per pixel 1" , "Fails on WinRT - QTBUG-68297" , Abort); |
2493 | QEXPECT_FAIL("column 5, scroll per pixel 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2494 | QEXPECT_FAIL("column 9, scroll per pixel 5" , "Fails on WinRT - QTBUG-68297" , Abort); |
2495 | #endif |
2496 | QCOMPARE(view.columnViewportPosition(column), columnViewportPosition); |
2497 | } |
2498 | |
2499 | void tst_QTableView::columnAt_data() |
2500 | { |
2501 | QTest::addColumn<int>(name: "columnCount" ); |
2502 | QTest::addColumn<int>(name: "columnWidth" ); |
2503 | QTest::addColumn<IntList>(name: "hiddenColumns" ); |
2504 | QTest::addColumn<int>(name: "coordinate" ); |
2505 | QTest::addColumn<int>(name: "column" ); |
2506 | |
2507 | QTest::newRow(dataTag: "column at 100" ) << 5 << 40 << IntList() << 100 << 2; |
2508 | QTest::newRow(dataTag: "column at 180" ) << 5 << 40 << IntList() << 180 << 4; |
2509 | QTest::newRow(dataTag: "column at 20" ) << 5 << 40 << IntList() << 20 << 0; |
2510 | |
2511 | // ### expand the dataset to include hidden coumns |
2512 | } |
2513 | |
2514 | void tst_QTableView::columnAt() |
2515 | { |
2516 | QFETCH(int, columnCount); |
2517 | QFETCH(int, columnWidth); |
2518 | QFETCH(IntList, hiddenColumns); |
2519 | QFETCH(int, coordinate); |
2520 | QFETCH(int, column); |
2521 | |
2522 | QtTestTableModel model(1, columnCount); |
2523 | QtTestTableView view; |
2524 | view.resize(w: 2 * columnWidth, h: 100); |
2525 | |
2526 | view.setModel(&model); |
2527 | |
2528 | for (int c = 0; c < columnCount; ++c) |
2529 | view.setColumnWidth(column: c, width: columnWidth); |
2530 | |
2531 | for (int i = 0; i < hiddenColumns.count(); ++i) |
2532 | view.hideColumn(column: hiddenColumns.at(i)); |
2533 | |
2534 | QCOMPARE(view.columnAt(coordinate), column); |
2535 | } |
2536 | |
2537 | void tst_QTableView::columnWidth_data() |
2538 | { |
2539 | QTest::addColumn<int>(name: "columnCount" ); |
2540 | QTest::addColumn<IntList>(name: "columnWidths" ); |
2541 | QTest::addColumn<BoolList>(name: "hiddenColumns" ); |
2542 | |
2543 | QTest::newRow(dataTag: "increasing" ) |
2544 | << 5 |
2545 | << (IntList() << 20 << 30 << 40 << 50 << 60) |
2546 | << (BoolList() << false << false << false << false << false); |
2547 | |
2548 | QTest::newRow(dataTag: "decreasing" ) |
2549 | << 5 |
2550 | << (IntList() << 60 << 50 << 40 << 30 << 20) |
2551 | << (BoolList() << false << false << false << false << false); |
2552 | |
2553 | QTest::newRow(dataTag: "random" ) |
2554 | << 5 |
2555 | << (IntList() << 87 << 34 << 68 << 91 << 27) |
2556 | << (BoolList() << false << false << false << false << false); |
2557 | |
2558 | // ### expand the dataset to include hidden columns |
2559 | } |
2560 | |
2561 | void tst_QTableView::columnWidth() |
2562 | { |
2563 | QFETCH(int, columnCount); |
2564 | QFETCH(IntList, columnWidths); |
2565 | QFETCH(BoolList, hiddenColumns); |
2566 | |
2567 | QtTestTableModel model(1, columnCount); |
2568 | QtTestTableView view; |
2569 | |
2570 | view.setModel(&model); |
2571 | |
2572 | for (int c = 0; c < columnCount; ++c) { |
2573 | view.setColumnWidth(column: c, width: columnWidths.at(i: c)); |
2574 | view.setColumnHidden(column: c, hide: hiddenColumns.at(i: c)); |
2575 | } |
2576 | |
2577 | for (int c = 0; c < columnCount; ++c) { |
2578 | if (hiddenColumns.at(i: c)) |
2579 | QCOMPARE(view.columnWidth(c), 0); |
2580 | else |
2581 | QCOMPARE(view.columnWidth(c), columnWidths.at(c)); |
2582 | } |
2583 | } |
2584 | |
2585 | void tst_QTableView::hiddenRow_data() |
2586 | { |
2587 | QTest::addColumn<int>(name: "rowCount" ); |
2588 | QTest::addColumn<BoolList>(name: "hiddenRows" ); |
2589 | |
2590 | QTest::newRow(dataTag: "first hidden" ) |
2591 | << 5 << (BoolList() << true << false << false << false << false); |
2592 | |
2593 | QTest::newRow(dataTag: "last hidden" ) |
2594 | << 5 << (BoolList() << false << false << false << false << true); |
2595 | |
2596 | QTest::newRow(dataTag: "none hidden" ) |
2597 | << 5 << (BoolList() << false << false << false << false << false); |
2598 | |
2599 | QTest::newRow(dataTag: "all hidden" ) |
2600 | << 5 << (BoolList() << true << true << true << true << true); |
2601 | } |
2602 | |
2603 | void tst_QTableView::hiddenRow() |
2604 | { |
2605 | QFETCH(int, rowCount); |
2606 | QFETCH(BoolList, hiddenRows); |
2607 | |
2608 | |
2609 | QtTestTableModel model(rowCount, 1); |
2610 | QtTestTableView view; |
2611 | |
2612 | view.setModel(&model); |
2613 | |
2614 | for (int r = 0; r < rowCount; ++r) |
2615 | QVERIFY(!view.isRowHidden(r)); |
2616 | |
2617 | for (int r = 0; r < rowCount; ++r) |
2618 | view.setRowHidden(row: r, hide: hiddenRows.at(i: r)); |
2619 | |
2620 | for (int r = 0; r < rowCount; ++r) |
2621 | QCOMPARE(view.isRowHidden(r), hiddenRows.at(r)); |
2622 | |
2623 | for (int r = 0; r < rowCount; ++r) |
2624 | view.setRowHidden(row: r, hide: false); |
2625 | |
2626 | for (int r = 0; r < rowCount; ++r) |
2627 | QVERIFY(!view.isRowHidden(r)); |
2628 | } |
2629 | |
2630 | void tst_QTableView::hiddenColumn_data() |
2631 | { |
2632 | QTest::addColumn<int>(name: "columnCount" ); |
2633 | QTest::addColumn<BoolList>(name: "hiddenColumns" ); |
2634 | |
2635 | QTest::newRow(dataTag: "first hidden" ) |
2636 | << 5 << (BoolList() << true << false << false << false << false); |
2637 | |
2638 | QTest::newRow(dataTag: "last hidden" ) |
2639 | << 5 << (BoolList() << false << false << false << false << true); |
2640 | |
2641 | QTest::newRow(dataTag: "none hidden" ) |
2642 | << 5 << (BoolList() << false << false << false << false << false); |
2643 | |
2644 | QTest::newRow(dataTag: "all hidden" ) |
2645 | << 5 << (BoolList() << true << true << true << true << true); |
2646 | } |
2647 | |
2648 | void tst_QTableView::hiddenColumn() |
2649 | { |
2650 | QFETCH(int, columnCount); |
2651 | QFETCH(BoolList, hiddenColumns); |
2652 | |
2653 | QtTestTableModel model(1, columnCount); |
2654 | QtTestTableView view; |
2655 | |
2656 | view.setModel(&model); |
2657 | |
2658 | for (int c = 0; c < columnCount; ++c) |
2659 | QVERIFY(!view.isColumnHidden(c)); |
2660 | |
2661 | for (int c = 0; c < columnCount; ++c) |
2662 | view.setColumnHidden(column: c, hide: hiddenColumns.at(i: c)); |
2663 | |
2664 | for (int c = 0; c < columnCount; ++c) |
2665 | QCOMPARE(view.isColumnHidden(c), hiddenColumns.at(c)); |
2666 | |
2667 | for (int c = 0; c < columnCount; ++c) |
2668 | view.setColumnHidden(column: c, hide: false); |
2669 | |
2670 | for (int c = 0; c < columnCount; ++c) |
2671 | QVERIFY(!view.isColumnHidden(c)); |
2672 | } |
2673 | |
2674 | void tst_QTableView::sortingEnabled_data() |
2675 | { |
2676 | // QTest::addColumn<int>("columnCount"); |
2677 | } |
2678 | |
2679 | void tst_QTableView::sortingEnabled() |
2680 | { |
2681 | // QFETCH(int, columnCount); |
2682 | } |
2683 | |
2684 | void tst_QTableView::sortByColumn_data() |
2685 | { |
2686 | QTest::addColumn<bool>(name: "sortingEnabled" ); |
2687 | QTest::newRow(dataTag: "sorting enabled" ) << true; |
2688 | QTest::newRow(dataTag: "sorting disabled" ) << false; |
2689 | } |
2690 | |
2691 | // Checks sorting and that sortByColumn also sets the sortIndicator |
2692 | void tst_QTableView::sortByColumn() |
2693 | { |
2694 | QFETCH(bool, sortingEnabled); |
2695 | QTableView view; |
2696 | QStandardItemModel model(4, 2); |
2697 | QSortFilterProxyModel sfpm; // default QStandardItemModel does not support 'unsorted' state |
2698 | sfpm.setSourceModel(&model); |
2699 | model.setItem(row: 0, column: 0, item: new QStandardItem("b" )); |
2700 | model.setItem(row: 1, column: 0, item: new QStandardItem("d" )); |
2701 | model.setItem(row: 2, column: 0, item: new QStandardItem("c" )); |
2702 | model.setItem(row: 3, column: 0, item: new QStandardItem("a" )); |
2703 | model.setItem(row: 0, column: 1, item: new QStandardItem("e" )); |
2704 | model.setItem(row: 1, column: 1, item: new QStandardItem("g" )); |
2705 | model.setItem(row: 2, column: 1, item: new QStandardItem("h" )); |
2706 | model.setItem(row: 3, column: 1, item: new QStandardItem("f" )); |
2707 | |
2708 | view.setSortingEnabled(sortingEnabled); |
2709 | view.setModel(&sfpm); |
2710 | view.show(); |
2711 | |
2712 | view.sortByColumn(column: 1, order: Qt::DescendingOrder); |
2713 | QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 1); |
2714 | QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("c" )); |
2715 | QCOMPARE(view.model()->data(view.model()->index(1, 0)).toString(), QString::fromLatin1("d" )); |
2716 | QCOMPARE(view.model()->data(view.model()->index(0, 1)).toString(), QString::fromLatin1("h" )); |
2717 | QCOMPARE(view.model()->data(view.model()->index(1, 1)).toString(), QString::fromLatin1("g" )); |
2718 | |
2719 | view.sortByColumn(column: 0, order: Qt::AscendingOrder); |
2720 | QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), 0); |
2721 | QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("a" )); |
2722 | QCOMPARE(view.model()->data(view.model()->index(1, 0)).toString(), QString::fromLatin1("b" )); |
2723 | QCOMPARE(view.model()->data(view.model()->index(0, 1)).toString(), QString::fromLatin1("f" )); |
2724 | QCOMPARE(view.model()->data(view.model()->index(1, 1)).toString(), QString::fromLatin1("e" )); |
2725 | |
2726 | view.sortByColumn(column: -1, order: Qt::AscendingOrder); |
2727 | QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), -1); |
2728 | QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("b" )); |
2729 | QCOMPARE(view.model()->data(view.model()->index(1, 0)).toString(), QString::fromLatin1("d" )); |
2730 | QCOMPARE(view.model()->data(view.model()->index(0, 1)).toString(), QString::fromLatin1("e" )); |
2731 | QCOMPARE(view.model()->data(view.model()->index(1, 1)).toString(), QString::fromLatin1("g" )); |
2732 | |
2733 | // a new 'sortByColumn()' should do a re-sort (e.g. due to the data changed), QTBUG-86268 |
2734 | view.setModel(&model); |
2735 | view.sortByColumn(column: 0, order: Qt::AscendingOrder); |
2736 | QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("a" )); |
2737 | model.setItem(row: 0, column: 0, item: new QStandardItem("x" )); |
2738 | view.sortByColumn(column: 0, order: Qt::AscendingOrder); |
2739 | QCOMPARE(view.model()->data(view.model()->index(0, 0)).toString(), QString::fromLatin1("b" )); |
2740 | } |
2741 | |
2742 | void tst_QTableView::scrollTo_data() |
2743 | { |
2744 | QTest::addColumn<QAbstractItemView::ScrollMode>(name: "verticalScrollMode" ); |
2745 | QTest::addColumn<QAbstractItemView::ScrollMode>(name: "horizontalScrollMode" ); |
2746 | QTest::addColumn<int>(name: "rowCount" ); |
2747 | QTest::addColumn<int>(name: "columnCount" ); |
2748 | QTest::addColumn<int>(name: "rowHeight" ); |
2749 | QTest::addColumn<int>(name: "columnWidth" ); |
2750 | QTest::addColumn<int>(name: "hiddenRow" ); |
2751 | QTest::addColumn<int>(name: "hiddenColumn" ); |
2752 | QTest::addColumn<int>(name: "row" ); |
2753 | QTest::addColumn<int>(name: "column" ); |
2754 | QTest::addColumn<int>(name: "rowSpan" ); |
2755 | QTest::addColumn<int>(name: "columnSpan" ); |
2756 | QTest::addColumn<int>(name: "horizontalScroll" ); |
2757 | QTest::addColumn<int>(name: "verticalScroll" ); |
2758 | QTest::addColumn<QAbstractItemView::ScrollHint>(name: "scrollHint" ); |
2759 | QTest::addColumn<int>(name: "expectedHorizontalScroll" ); |
2760 | QTest::addColumn<int>(name: "expectedVerticalScroll" ); |
2761 | |
2762 | QTest::newRow(dataTag: "no hidden, no span, no scroll, per item" ) |
2763 | << QAbstractItemView::ScrollPerItem |
2764 | << QAbstractItemView::ScrollPerItem |
2765 | << 10 << 10 // table |
2766 | << 80 << 80 // size |
2767 | << -1 << -1 // hide |
2768 | << 0 << 0 // cell |
2769 | << 1 << 1 // span |
2770 | << 0 << 0 // scroll |
2771 | << QAbstractItemView::PositionAtTop |
2772 | << 0 << 0; // expected |
2773 | |
2774 | QTest::newRow(dataTag: "no hidden, no span, no scroll, per pixel" ) |
2775 | << QAbstractItemView::ScrollPerPixel |
2776 | << QAbstractItemView::ScrollPerPixel |
2777 | << 10 << 10 // table |
2778 | << 80 << 80 // size |
2779 | << -1 << -1 // hide |
2780 | << 0 << 0 // cell |
2781 | << 1 << 1 // span |
2782 | << 0 << 0 // scroll |
2783 | << QAbstractItemView::PositionAtTop |
2784 | << 0 << 0; // expected |
2785 | |
2786 | QTest::newRow(dataTag: "hidden, no span, no scroll, per item" ) |
2787 | << QAbstractItemView::ScrollPerItem |
2788 | << QAbstractItemView::ScrollPerItem |
2789 | << 10 << 10 // table |
2790 | << 80 << 80 // size |
2791 | << 3 << 3 // hide |
2792 | << 5 << 5 // cell |
2793 | << 1 << 1 // span |
2794 | << 0 << 0 // scroll |
2795 | << QAbstractItemView::PositionAtTop |
2796 | << 4 << 4; // expected |
2797 | } |
2798 | |
2799 | void tst_QTableView::scrollTo() |
2800 | { |
2801 | QFETCH(QAbstractItemView::ScrollMode, horizontalScrollMode); |
2802 | QFETCH(QAbstractItemView::ScrollMode, verticalScrollMode); |
2803 | QFETCH(int, rowCount); |
2804 | QFETCH(int, columnCount); |
2805 | QFETCH(int, rowHeight); |
2806 | QFETCH(int, columnWidth); |
2807 | QFETCH(int, hiddenRow); |
2808 | QFETCH(int, hiddenColumn); |
2809 | QFETCH(int, row); |
2810 | QFETCH(int, column); |
2811 | QFETCH(int, rowSpan); |
2812 | QFETCH(int, columnSpan); |
2813 | QFETCH(int, horizontalScroll); |
2814 | QFETCH(int, verticalScroll); |
2815 | QFETCH(QAbstractItemView::ScrollHint, scrollHint); |
2816 | QFETCH(int, expectedHorizontalScroll); |
2817 | QFETCH(int, expectedVerticalScroll); |
2818 | |
2819 | QtTestTableModel model(rowCount, columnCount); |
2820 | QWidget toplevel; |
2821 | setFrameless(&toplevel); |
2822 | QtTestTableView view(&toplevel); |
2823 | |
2824 | toplevel.show(); |
2825 | // resizing to this size will ensure that there can ONLY_BE_ONE_CELL inside the view. |
2826 | QSize forcedSize(columnWidth * 2, rowHeight * 2); |
2827 | view.resize(forcedSize); |
2828 | QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); |
2829 | QTRY_COMPARE(view.size(), forcedSize); |
2830 | |
2831 | view.setModel(&model); |
2832 | view.setSpan(row, column, rowSpan, columnSpan); |
2833 | view.hideRow(row: hiddenRow); |
2834 | view.hideColumn(column: hiddenColumn); |
2835 | view.setHorizontalScrollMode(horizontalScrollMode); |
2836 | view.setVerticalScrollMode(verticalScrollMode); |
2837 | |
2838 | for (int r = 0; r < rowCount; ++r) |
2839 | view.setRowHeight(row: r, height: rowHeight); |
2840 | for (int c = 0; c < columnCount; ++c) |
2841 | view.setColumnWidth(column: c, width: columnWidth); |
2842 | |
2843 | view.horizontalScrollBar()->setValue(horizontalScroll); |
2844 | view.verticalScrollBar()->setValue(verticalScroll); |
2845 | |
2846 | QModelIndex index = model.index(row, column); |
2847 | QVERIFY(index.isValid()); |
2848 | view.scrollTo(index, hint: scrollHint); |
2849 | QTRY_COMPARE(view.verticalScrollBar()->value(), expectedVerticalScroll); |
2850 | QTRY_COMPARE(view.horizontalScrollBar()->value(), expectedHorizontalScroll); |
2851 | } |
2852 | |
2853 | void tst_QTableView::indexAt_data() |
2854 | { |
2855 | QTest::addColumn<int>(name: "rowCount" ); |
2856 | QTest::addColumn<int>(name: "columnCount" ); |
2857 | |
2858 | QTest::addColumn<int>(name: "rowHeight" ); |
2859 | QTest::addColumn<int>(name: "columnWidth" ); |
2860 | |
2861 | QTest::addColumn<int>(name: "hiddenRow" ); |
2862 | QTest::addColumn<int>(name: "hiddenColumn" ); |
2863 | |
2864 | QTest::addColumn<int>(name: "row" ); |
2865 | QTest::addColumn<int>(name: "column" ); |
2866 | QTest::addColumn<int>(name: "rowSpan" ); |
2867 | QTest::addColumn<int>(name: "columnSpan" ); |
2868 | QTest::addColumn<int>(name: "horizontalScroll" ); |
2869 | QTest::addColumn<int>(name: "verticalScroll" ); |
2870 | QTest::addColumn<int>(name: "x" ); |
2871 | QTest::addColumn<int>(name: "y" ); |
2872 | QTest::addColumn<int>(name: "expectedRow" ); |
2873 | QTest::addColumn<int>(name: "expectedColumn" ); |
2874 | |
2875 | QTest::newRow(dataTag: "no hidden, no span, no scroll, (20,20)" ) |
2876 | << 10 << 10 // dim |
2877 | << 40 << 40 // size |
2878 | << -1 << -1 // hide |
2879 | << -1 << -1 // pos |
2880 | << 1 << 1 // span |
2881 | << 0 << 0 // scroll |
2882 | << 20 << 20 // point |
2883 | << 0 << 0; // expected |
2884 | |
2885 | QTest::newRow(dataTag: "row hidden, no span, no scroll, at (20,20)" ) |
2886 | << 10 << 10 // dim |
2887 | << 40 << 40 // size |
2888 | << 0 << -1 // hide |
2889 | << -1 << -1 // pos |
2890 | << 1 << 1 // span |
2891 | << 0 << 0 // scroll |
2892 | << 20 << 20 // point |
2893 | << 1 << 0; // expected |
2894 | |
2895 | QTest::newRow(dataTag: "col hidden, no span, no scroll, at (20,20)" ) |
2896 | << 10 << 10 // dim |
2897 | << 40 << 40 // size |
2898 | << -1 << 0 // hide |
2899 | << -1 << -1 // pos |
2900 | << 1 << 1 // span |
2901 | << 0 << 0 // scroll |
2902 | << 20 << 20 // point |
2903 | << 0 << 1; // expected |
2904 | |
2905 | QTest::newRow(dataTag: "no hidden, row span, no scroll, at (60,20)" ) |
2906 | << 10 << 10 // dim |
2907 | << 40 << 40 // size |
2908 | << -1 << -1 // hide |
2909 | << 0 << 0 // pos |
2910 | << 2 << 1 // span |
2911 | << 0 << 0 // scroll |
2912 | << 20 << 60 // point |
2913 | << 0 << 0; // expected |
2914 | |
2915 | |
2916 | QTest::newRow(dataTag: "no hidden, col span, no scroll, at (60,20)" ) |
2917 | << 10 << 10 // dim |
2918 | << 40 << 40 // size |
2919 | << -1 << -1 // hide |
2920 | << 0 << 0 // pos |
2921 | << 1 << 2 // span |
2922 | << 0 << 0 // scroll |
2923 | << 60 << 20 // point |
2924 | << 0 << 0; // expected |
2925 | |
2926 | QTest::newRow(dataTag: "no hidden, no span, scroll (5,0), at (20,20)" ) |
2927 | << 20 << 20 // dim |
2928 | << 40 << 40 // size |
2929 | << -1 << -1 // hide |
2930 | << -1 << -1 // pos |
2931 | << 1 << 1 // span |
2932 | << 5 << 0 // scroll |
2933 | << 20 << 20 // point |
2934 | << 0 << 5; // expected |
2935 | |
2936 | QTest::newRow(dataTag: "no hidden, no span, scroll (0,5), at (20,20)" ) |
2937 | << 20 << 20 // dim |
2938 | << 40 << 40 // size |
2939 | << -1 << -1 // hide |
2940 | << -1 << -1 // pos |
2941 | << 1 << 1 // span |
2942 | << 0 << 5 // scroll |
2943 | << 20 << 20 // point |
2944 | << 5 << 0; // expected |
2945 | |
2946 | QTest::newRow(dataTag: "no hidden, no span, scroll (5,5), at (20,20)" ) |
2947 | << 20 << 20 // dim |
2948 | << 40 << 40 // size |
2949 | << -1 << -1 // hide |
2950 | << -1 << -1 // pos |
2951 | << 1 << 1 // span |
2952 | << 5 << 5 // scroll |
2953 | << 20 << 20 // point |
2954 | << 5 << 5; // expected |
2955 | } |
2956 | |
2957 | void tst_QTableView::indexAt() |
2958 | { |
2959 | QFETCH(int, rowCount); |
2960 | QFETCH(int, columnCount); |
2961 | QFETCH(int, rowHeight); |
2962 | QFETCH(int, columnWidth); |
2963 | QFETCH(int, hiddenRow); |
2964 | QFETCH(int, hiddenColumn); |
2965 | QFETCH(int, row); |
2966 | QFETCH(int, column); |
2967 | QFETCH(int, rowSpan); |
2968 | QFETCH(int, columnSpan); |
2969 | QFETCH(int, horizontalScroll); |
2970 | QFETCH(int, verticalScroll); |
2971 | QFETCH(int, x); |
2972 | QFETCH(int, y); |
2973 | QFETCH(int, expectedRow); |
2974 | QFETCH(int, expectedColumn); |
2975 | |
2976 | QtTestTableModel model(rowCount, columnCount); |
2977 | QWidget toplevel; |
2978 | QtTestTableView view(&toplevel); |
2979 | |
2980 | toplevel.show(); |
2981 | QVERIFY(QTest::qWaitForWindowExposed(&toplevel)); |
2982 | |
2983 | //some styles change the scroll mode in their polish |
2984 | view.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); |
2985 | view.setVerticalScrollMode(QAbstractItemView::ScrollPerItem); |
2986 | |
2987 | view.setModel(&model); |
2988 | view.setSpan(row, column, rowSpan, columnSpan); |
2989 | view.hideRow(row: hiddenRow); |
2990 | view.hideColumn(column: hiddenColumn); |
2991 | |
2992 | for (int r = 0; r < rowCount; ++r) |
2993 | view.setRowHeight(row: r, height: rowHeight); |
2994 | for (int c = 0; c < columnCount; ++c) |
2995 | view.setColumnWidth(column: c, width: columnWidth); |
2996 | |
2997 | view.horizontalScrollBar()->setValue(horizontalScroll); |
2998 | view.verticalScrollBar()->setValue(verticalScroll); |
2999 | |
3000 | QModelIndex index = view.indexAt(p: QPoint(x, y)); |
3001 | QTRY_COMPARE(index.row(), expectedRow); |
3002 | QTRY_COMPARE(index.column(), expectedColumn); |
3003 | } |
3004 | |
3005 | void tst_QTableView::span_data() |
3006 | { |
3007 | QTest::addColumn<int>(name: "rowCount" ); |
3008 | QTest::addColumn<int>(name: "columnCount" ); |
3009 | QTest::addColumn<int>(name: "hiddenRow" ); |
3010 | QTest::addColumn<int>(name: "hiddenColumn" ); |
3011 | QTest::addColumn<int>(name: "row" ); |
3012 | QTest::addColumn<int>(name: "column" ); |
3013 | QTest::addColumn<int>(name: "rowSpan" ); |
3014 | QTest::addColumn<int>(name: "columnSpan" ); |
3015 | QTest::addColumn<int>(name: "expectedRowSpan" ); |
3016 | QTest::addColumn<int>(name: "expectedColumnSpan" ); |
3017 | QTest::addColumn<bool>(name: "clear" ); |
3018 | |
3019 | QTest::newRow(dataTag: "top left 2x2" ) |
3020 | << 10 << 10 |
3021 | << -1 << -1 |
3022 | << 0 << 0 |
3023 | << 2 << 2 |
3024 | << 2 << 2 |
3025 | << false; |
3026 | |
3027 | QTest::newRow(dataTag: "top left 1x2" ) |
3028 | << 10 << 10 |
3029 | << 3 << 3 |
3030 | << 0 << 0 |
3031 | << 1 << 2 |
3032 | << 1 << 2 |
3033 | << false; |
3034 | |
3035 | QTest::newRow(dataTag: "top left 2x1" ) |
3036 | << 10 << 10 |
3037 | << -1 << -1 |
3038 | << 0 << 0 |
3039 | << 2 << 1 |
3040 | << 2 << 1 |
3041 | << false; |
3042 | |
3043 | /* This makes no sens. |
3044 | QTest::newRow("top left 2x0") |
3045 | << 10 << 10 |
3046 | << -1 << -1 |
3047 | << 0 << 0 |
3048 | << 2 << 0 |
3049 | << 2 << 0 |
3050 | << false; |
3051 | |
3052 | QTest::newRow("top left 0x2") |
3053 | << 10 << 10 |
3054 | << -1 << -1 |
3055 | << 0 << 0 |
3056 | << 0 << 2 |
3057 | << 0 << 2 |
3058 | << false;*/ |
3059 | |
3060 | QTest::newRow(dataTag: "invalid 2x2" ) |
3061 | << 10 << 10 |
3062 | << -1 << -1 |
3063 | << -1 << -1 |
3064 | << 2 << 2 |
3065 | << 1 << 1 |
3066 | << false; |
3067 | |
3068 | QTest::newRow(dataTag: "top left 2x2" ) |
3069 | << 10 << 10 |
3070 | << -1 << -1 |
3071 | << 0 << 0 |
3072 | << 2 << 2 |
3073 | << 2 << 2 |
3074 | << false; |
3075 | |
3076 | QTest::newRow(dataTag: "bottom right 2x2" ) |
3077 | << 10 << 10 |
3078 | << -1 << -1 |
3079 | << 8 << 8 |
3080 | << 2 << 2 |
3081 | << 2 << 2 |
3082 | << false; |
3083 | |
3084 | QTest::newRow(dataTag: "invalid span 2x2" ) |
3085 | << 10 << 10 |
3086 | << -1 << -1 |
3087 | << 8 << 8 |
3088 | << 2 << 2 |
3089 | << 2 << 2 |
3090 | << false; |
3091 | |
3092 | QTest::newRow(dataTag: "invalid span 3x3" ) |
3093 | << 10 << 10 |
3094 | << -1 << -1 |
3095 | << 6 << 6 |
3096 | << 3 << 3 |
3097 | << 2 << 3 |
3098 | << true; |
3099 | |
3100 | } |
3101 | |
3102 | void tst_QTableView::span() |
3103 | { |
3104 | QFETCH(int, rowCount); |
3105 | QFETCH(int, columnCount); |
3106 | QFETCH(int, hiddenRow); |
3107 | QFETCH(int, hiddenColumn); |
3108 | QFETCH(int, row); |
3109 | QFETCH(int, column); |
3110 | QFETCH(int, rowSpan); |
3111 | QFETCH(int, columnSpan); |
3112 | QFETCH(int, expectedRowSpan); |
3113 | QFETCH(int, expectedColumnSpan); |
3114 | QFETCH(bool, clear); |
3115 | |
3116 | QtTestTableModel model(rowCount, columnCount); |
3117 | QtTestTableView view; |
3118 | |
3119 | view.setModel(&model); |
3120 | view.show(); |
3121 | |
3122 | view.setSpan(row, column, rowSpan, columnSpan); |
3123 | if (clear) { |
3124 | model.removeLastRow(); |
3125 | model.removeLastRow(); |
3126 | view.update(); |
3127 | } |
3128 | |
3129 | view.hideRow(row: hiddenRow); |
3130 | view.hideColumn(column: hiddenColumn); |
3131 | view.show(); |
3132 | |
3133 | QCOMPARE(view.rowSpan(row, column), expectedRowSpan); |
3134 | QCOMPARE(view.columnSpan(row, column), expectedColumnSpan); |
3135 | |
3136 | if (hiddenRow > -1) { |
3137 | QModelIndex hidden = model.index(row: hiddenRow, column: columnCount - 1); |
3138 | QVERIFY(view.isIndexHidden(hidden)); |
3139 | } |
3140 | |
3141 | if (hiddenColumn > -1) { |
3142 | QModelIndex hidden = model.index(row: rowCount - 1, column: hiddenColumn); |
3143 | QVERIFY(view.isIndexHidden(hidden)); |
3144 | } |
3145 | |
3146 | view.clearSpans(); |
3147 | QCOMPARE(view.rowSpan(row, column), 1); |
3148 | QCOMPARE(view.columnSpan(row, column), 1); |
3149 | |
3150 | VERIFY_SPANS_CONSISTENCY(&view); |
3151 | } |
3152 | |
3153 | void tst_QTableView::spans_data() |
3154 | { |
3155 | QTest::addColumn<int>(name: "rows" ); |
3156 | QTest::addColumn<int>(name: "columns" ); |
3157 | QTest::addColumn<SpanList>(name: "spans" ); |
3158 | QTest::addColumn<bool>(name: "hideRowLastRowOfFirstSpan" ); |
3159 | QTest::addColumn<QPoint>(name: "pos" ); |
3160 | QTest::addColumn<int>(name: "expectedRowSpan" ); |
3161 | QTest::addColumn<int>(name: "expectedColumnSpan" ); |
3162 | |
3163 | QTest::newRow(dataTag: "1x3 span, query 3,0" ) |
3164 | << 5 << 5 |
3165 | << (SpanList() << QRect(3, 0, 1, 3)) |
3166 | << false //no hidden row |
3167 | << QPoint(3, 0) |
3168 | << 1 |
3169 | << 3; |
3170 | |
3171 | QTest::newRow(dataTag: "1x3 span, query 3,1" ) |
3172 | << 5 << 5 |
3173 | << (SpanList() << QRect(3, 0, 1, 3)) |
3174 | << false //no hidden row |
3175 | << QPoint(3, 1) |
3176 | << 1 |
3177 | << 3; |
3178 | |
3179 | QTest::newRow(dataTag: "1x3 span, query 3,2" ) |
3180 | << 5 << 5 |
3181 | << (SpanList() << QRect(3, 0, 1, 3)) |
3182 | << false //no hidden row |
3183 | << QPoint(3, 2) |
3184 | << 1 |
3185 | << 3; |
3186 | |
3187 | QTest::newRow(dataTag: "two 1x2 spans at the same column, query at 3,0" ) |
3188 | << 5 << 5 |
3189 | << (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2)) |
3190 | << false //no hidden row |
3191 | << QPoint(3, 0) |
3192 | << 1 |
3193 | << 2; |
3194 | |
3195 | QTest::newRow(dataTag: "two 1x2 spans at the same column, query at 4,0" ) |
3196 | << 5 << 5 |
3197 | << (SpanList() << QRect(3, 0, 1, 2) << QRect(4, 0, 1, 2)) |
3198 | << false //no hidden row |
3199 | << QPoint(4, 0) |
3200 | << 1 |
3201 | << 2; |
3202 | |
3203 | QTest::newRow(dataTag: "how to order spans (1,1)" ) |
3204 | << 5 << 5 |
3205 | << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
3206 | << false //no hidden row |
3207 | << QPoint(1, 1) |
3208 | << 3 |
3209 | << 1; |
3210 | |
3211 | QTest::newRow(dataTag: "how to order spans (2,1)" ) |
3212 | << 5 << 5 |
3213 | << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
3214 | << false //no hidden row |
3215 | << QPoint(2, 1) |
3216 | << 3 |
3217 | << 1; |
3218 | |
3219 | QTest::newRow(dataTag: "how to order spans (3,1)" ) |
3220 | << 5 << 5 |
3221 | << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
3222 | << false //no hidden row |
3223 | << QPoint(3, 1) |
3224 | << 3 |
3225 | << 1; |
3226 | |
3227 | QTest::newRow(dataTag: "how to order spans (1,2)" ) |
3228 | << 5 << 5 |
3229 | << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
3230 | << false //no hidden row |
3231 | << QPoint(1, 2) |
3232 | << 2 |
3233 | << 1; |
3234 | |
3235 | QTest::newRow(dataTag: "how to order spans (2,2)" ) |
3236 | << 5 << 5 |
3237 | << (SpanList() << QRect(1, 1, 3, 1) << QRect(1, 2, 2, 1)) |
3238 | << false //no hidden row |
3239 | << QPoint(2, 2) |
3240 | << 2 |
3241 | << 1; |
3242 | |
3243 | QTest::newRow(dataTag: "spans with hidden rows" ) |
3244 | << 3 << 2 |
3245 | << (SpanList() << QRect(0, 0, 2, 2) << QRect(2, 0, 1, 2)) |
3246 | << true //we hide the last row of the first span |
3247 | << QPoint(2, 0) |
3248 | << 1 |
3249 | << 2; |
3250 | |
3251 | QTest::newRow(dataTag: "QTBUG-6004: No failing assertion, then it passes." ) |
3252 | << 5 << 5 |
3253 | << (SpanList() << QRect(0, 0, 2, 2) << QRect(0, 0, 1, 1)) |
3254 | << false |
3255 | << QPoint(0, 0) |
3256 | << 1 |
3257 | << 1; |
3258 | |
3259 | QTest::newRow(dataTag: "QTBUG-6004 (follow-up): No failing assertion, then it passes." ) |
3260 | << 10 << 10 |
3261 | << (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1)) |
3262 | << false |
3263 | << QPoint(0, 0) |
3264 | << 1 |
3265 | << 1; |
3266 | |
3267 | QTest::newRow(dataTag: "QTBUG-9631: remove one span" ) |
3268 | << 10 << 10 |
3269 | << (SpanList() << QRect(1, 1, 2, 1) << QRect(2, 2, 2, 2) << QRect(1, 1, 1, 1)) |
3270 | << false |
3271 | << QPoint(1, 1) |
3272 | << 1 |
3273 | << 1; |
3274 | } |
3275 | |
3276 | void tst_QTableView::spans() |
3277 | { |
3278 | QFETCH(int, rows); |
3279 | QFETCH(int, columns); |
3280 | QFETCH(const SpanList, spans); |
3281 | QFETCH(bool, hideRowLastRowOfFirstSpan); |
3282 | QFETCH(QPoint, pos); |
3283 | QFETCH(int, expectedRowSpan); |
3284 | QFETCH(int, expectedColumnSpan); |
3285 | |
3286 | QtTestTableModel model(rows, columns); |
3287 | QtTestTableView view; |
3288 | |
3289 | view.setModel(&model); |
3290 | view.show(); |
3291 | |
3292 | for (const auto &sp : spans) |
3293 | view.setSpan(row: sp.x(), column: sp.y(), rowSpan: sp.width(), columnSpan: sp.height()); |
3294 | |
3295 | if (hideRowLastRowOfFirstSpan) { |
3296 | view.setRowHidden(row: spans.at(i: 0).bottom(), hide: true); |
3297 | //we check that the span didn't break the visual rects of the model indexes |
3298 | QRect first = view.visualRect( index: model.index(row: spans.at(i: 0).top(), column: 0)); |
3299 | QRect next = view.visualRect( index: model.index(row: spans.at(i: 0).bottom() + 1, column: 0)); |
3300 | QVERIFY(first.intersected(next).isEmpty()); |
3301 | } |
3302 | |
3303 | QCOMPARE(view.columnSpan(pos.x(), pos.y()), expectedColumnSpan); |
3304 | QCOMPARE(view.rowSpan(pos.x(), pos.y()), expectedRowSpan); |
3305 | |
3306 | VERIFY_SPANS_CONSISTENCY(&view); |
3307 | } |
3308 | |
3309 | void tst_QTableView::spansAfterRowInsertion() |
3310 | { |
3311 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
3312 | QSKIP("Wayland: This fails. Figure out why." ); |
3313 | |
3314 | QtTestTableModel model(10, 10); |
3315 | QtTestTableView view; |
3316 | view.setModel(&model); |
3317 | view.setSpan(row: 3, column: 3, rowSpan: 3, columnSpan: 3); |
3318 | view.show(); |
3319 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
3320 | |
3321 | // Insertion before the span only shifts the span. |
3322 | view.model()->insertRows(row: 0, count: 2); |
3323 | QCOMPARE(view.rowSpan(3, 3), 1); |
3324 | QCOMPARE(view.columnSpan(3, 3), 1); |
3325 | QCOMPARE(view.rowSpan(5, 3), 3); |
3326 | QCOMPARE(view.columnSpan(5, 3), 3); |
3327 | |
3328 | // Insertion happens before the given row, so it only shifts the span also. |
3329 | view.model()->insertRows(row: 5, count: 2); |
3330 | QCOMPARE(view.rowSpan(5, 3), 1); |
3331 | QCOMPARE(view.columnSpan(5, 3), 1); |
3332 | QCOMPARE(view.rowSpan(7, 3), 3); |
3333 | QCOMPARE(view.columnSpan(7, 3), 3); |
3334 | |
3335 | // Insertion inside the span expands it. |
3336 | view.model()->insertRows(row: 8, count: 2); |
3337 | QCOMPARE(view.rowSpan(7, 3), 5); |
3338 | QCOMPARE(view.columnSpan(7, 3), 3); |
3339 | |
3340 | // Insertion after the span does nothing to it. |
3341 | view.model()->insertRows(row: 12, count: 2); |
3342 | QCOMPARE(view.rowSpan(7, 3), 5); |
3343 | QCOMPARE(view.columnSpan(7, 3), 3); |
3344 | |
3345 | VERIFY_SPANS_CONSISTENCY(&view); |
3346 | } |
3347 | |
3348 | void tst_QTableView::spansAfterColumnInsertion() |
3349 | { |
3350 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
3351 | QSKIP("Wayland: This fails. Figure out why." ); |
3352 | |
3353 | QtTestTableModel model(10, 10); |
3354 | QtTestTableView view; |
3355 | view.setModel(&model); |
3356 | view.setSpan(row: 3, column: 3, rowSpan: 3, columnSpan: 3); |
3357 | view.show(); |
3358 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
3359 | |
3360 | // Insertion before the span only shifts the span. |
3361 | view.model()->insertColumns(column: 0, count: 2); |
3362 | QCOMPARE(view.rowSpan(3, 3), 1); |
3363 | QCOMPARE(view.columnSpan(3, 3), 1); |
3364 | QCOMPARE(view.rowSpan(3, 5), 3); |
3365 | QCOMPARE(view.columnSpan(3, 5), 3); |
3366 | |
3367 | // Insertion happens before the given column, so it only shifts the span also. |
3368 | view.model()->insertColumns(column: 5, count: 2); |
3369 | QCOMPARE(view.rowSpan(3, 5), 1); |
3370 | QCOMPARE(view.columnSpan(3, 5), 1); |
3371 | QCOMPARE(view.rowSpan(3, 7), 3); |
3372 | QCOMPARE(view.columnSpan(3, 7), 3); |
3373 | |
3374 | // Insertion inside the span expands it. |
3375 | view.model()->insertColumns(column: 8, count: 2); |
3376 | QCOMPARE(view.rowSpan(3, 7), 3); |
3377 | QCOMPARE(view.columnSpan(3, 7), 5); |
3378 | |
3379 | // Insertion after the span does nothing to it. |
3380 | view.model()->insertColumns(column: 12, count: 2); |
3381 | QCOMPARE(view.rowSpan(3, 7), 3); |
3382 | QCOMPARE(view.columnSpan(3, 7), 5); |
3383 | |
3384 | VERIFY_SPANS_CONSISTENCY(&view); |
3385 | } |
3386 | |
3387 | void tst_QTableView::spansAfterRowRemoval() |
3388 | { |
3389 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
3390 | QSKIP("Wayland: This fails. Figure out why." ); |
3391 | |
3392 | QtTestTableModel model(10, 10); |
3393 | QtTestTableView view; |
3394 | view.setModel(&model); |
3395 | |
3396 | static const QRect spans[] = { |
3397 | {0, 1, 1, 2}, |
3398 | {1, 2, 1, 2}, |
3399 | {2, 2, 1, 5}, |
3400 | {2, 8, 1, 2}, |
3401 | {3, 4, 1, 2}, |
3402 | {4, 4, 1, 4}, |
3403 | {5, 6, 1, 3}, |
3404 | {6, 7, 1, 3} |
3405 | }; |
3406 | for (const QRect &span : spans) |
3407 | view.setSpan(row: span.top(), column: span.left(), rowSpan: span.height(), columnSpan: span.width()); |
3408 | |
3409 | view.show(); |
3410 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
3411 | view.model()->removeRows(row: 3, count: 3); |
3412 | |
3413 | static const QRect expectedSpans[] = { |
3414 | {0, 1, 1, 2}, |
3415 | {1, 2, 1, 1}, |
3416 | {2, 2, 1, 2}, |
3417 | {2, 5, 1, 2}, |
3418 | {3, 4, 1, 1}, |
3419 | {4, 3, 1, 2}, |
3420 | {5, 3, 1, 3}, |
3421 | {6, 4, 1, 3} |
3422 | }; |
3423 | for (const QRect &span : expectedSpans) { |
3424 | QCOMPARE(view.columnSpan(span.top(), span.left()), span.width()); |
3425 | QCOMPARE(view.rowSpan(span.top(), span.left()), span.height()); |
3426 | } |
3427 | |
3428 | VERIFY_SPANS_CONSISTENCY(&view); |
3429 | } |
3430 | |
3431 | void tst_QTableView::spansAfterColumnRemoval() |
3432 | { |
3433 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
3434 | QSKIP("Wayland: This fails. Figure out why." ); |
3435 | |
3436 | QtTestTableModel model(10, 10); |
3437 | QtTestTableView view; |
3438 | view.setModel(&model); |
3439 | |
3440 | // Same set as above just swapping columns and rows. |
3441 | static const QRect spans[] = { |
3442 | {0, 1, 1, 2}, |
3443 | {1, 2, 1, 2}, |
3444 | {2, 2, 1, 5}, |
3445 | {2, 8, 1, 2}, |
3446 | {3, 4, 1, 2}, |
3447 | {4, 4, 1, 4}, |
3448 | {5, 6, 1, 3}, |
3449 | {6, 7, 1, 3} |
3450 | }; |
3451 | for (const QRect &span : spans) |
3452 | view.setSpan(row: span.left(), column: span.top(), rowSpan: span.width(), columnSpan: span.height()); |
3453 | |
3454 | view.show(); |
3455 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
3456 | view.model()->removeColumns(column: 3, count: 3); |
3457 | |
3458 | static const QRect expectedSpans[] = { |
3459 | {0, 1, 1, 2}, |
3460 | {1, 2, 1, 1}, |
3461 | {2, 2, 1, 2}, |
3462 | {2, 5, 1, 2}, |
3463 | {3, 4, 1, 1}, |
3464 | {4, 3, 1, 2}, |
3465 | {5, 3, 1, 3}, |
3466 | {6, 4, 1, 3} |
3467 | }; |
3468 | for (const QRect &span : expectedSpans) { |
3469 | QCOMPARE(view.columnSpan(span.left(), span.top()), span.height()); |
3470 | QCOMPARE(view.rowSpan(span.left(), span.top()), span.width()); |
3471 | } |
3472 | |
3473 | VERIFY_SPANS_CONSISTENCY(&view); |
3474 | } |
3475 | |
3476 | void tst_QTableView::editSpanFromDirections_data() |
3477 | { |
3478 | QTest::addColumn<KeyList>(name: "keyPresses" ); |
3479 | QTest::addColumn<QSharedPointer<QStandardItemModel>>(name: "model" ); |
3480 | QTest::addColumn<int>(name: "row" ); |
3481 | QTest::addColumn<int>(name: "column" ); |
3482 | QTest::addColumn<int>(name: "rowSpan" ); |
3483 | QTest::addColumn<int>(name: "columnSpan" ); |
3484 | QTest::addColumn<QModelIndex>(name: "expectedVisualCursorIndex" ); |
3485 | QTest::addColumn<QModelIndex>(name: "expectedEditedIndex" ); |
3486 | |
3487 | /* x = the cell that should be edited |
3488 | c = the cell that should actually be the current index |
3489 | +---+---+ |
3490 | | | | |
3491 | +---+---+ |
3492 | | | x | |
3493 | +---+ + |
3494 | | | c | |
3495 | +---+---+ |
3496 | | | ^ | |
3497 | +---+---+ */ |
3498 | KeyList keyPresses {Qt::Key_Right, Qt::Key_PageDown, Qt::Key_Up}; |
3499 | QSharedPointer<QStandardItemModel> model(new QStandardItemModel(4, 2)); |
3500 | QTest::newRow(dataTag: "row span, bottom up" ) |
3501 | << keyPresses << model << 1 << 1 << 2 << 1 << model->index(row: 2, column: 1) << model->index(row: 1, column: 1); |
3502 | |
3503 | /* +---+---+ |
3504 | | | v | |
3505 | +---+---+ |
3506 | | |x,c| |
3507 | +---+ + |
3508 | | | | |
3509 | +---+---+ |
3510 | | | | |
3511 | +---+---+ */ |
3512 | keyPresses = {Qt::Key_Right, Qt::Key_Down}; |
3513 | model = QSharedPointer<QStandardItemModel>::create(arguments: 4, arguments: 2); |
3514 | QTest::newRow(dataTag: "row span, top down" ) |
3515 | << keyPresses << model << 1 << 1 << 2 << 1 << model->index(row: 1, column: 1) << model->index(row: 1, column: 1); |
3516 | |
3517 | /* +---+---+---+ |
3518 | | | | | |
3519 | +---+---+---+ |
3520 | | |x,c| < | |
3521 | +---+ +---+ |
3522 | | | | | |
3523 | +---+---+---+ */ |
3524 | keyPresses = {Qt::Key_End, Qt::Key_Down, Qt::Key_Left}; |
3525 | model = QSharedPointer<QStandardItemModel>::create(arguments: 3, arguments: 3); |
3526 | QTest::newRow(dataTag: "row span, right to left" ) |
3527 | << keyPresses << model << 1 << 1 << 2 << 1 << model->index(row: 1, column: 1) << model->index(row: 1, column: 1); |
3528 | |
3529 | /* +---+---+---+ |
3530 | | | | | |
3531 | +---+---+---+ |
3532 | | | x | | |
3533 | +---+ +---+ |
3534 | | > | c | | |
3535 | +---+---+---+ */ |
3536 | keyPresses = {Qt::Key_PageDown, Qt::Key_Right}; |
3537 | model = QSharedPointer<QStandardItemModel>::create(arguments: 3, arguments: 3); |
3538 | QTest::newRow(dataTag: "row span, left to right" ) |
3539 | << keyPresses << model << 1 << 1 << 2 << 1 << model->index(row: 2, column: 1) << model->index(row: 1, column: 1); |
3540 | |
3541 | /* +---+---+---+ |
3542 | | | | | |
3543 | +---+---+---+ |
3544 | |x,c | |
3545 | +---+---+---+ |
3546 | | ^ | | | |
3547 | +---+---+---+ */ |
3548 | keyPresses = {Qt::Key_PageDown, Qt::Key_Up}; |
3549 | model = QSharedPointer<QStandardItemModel>::create(arguments: 3, arguments: 3); |
3550 | QTest::newRow(dataTag: "col span, bottom up" ) |
3551 | << keyPresses << model << 1 << 0 << 1 << 3 << model->index(row: 1, column: 0) << model->index(row: 1, column: 0); |
3552 | |
3553 | /* +---+---+---+ |
3554 | | | | | |
3555 | +---+---+---+ |
3556 | | x c | |
3557 | +---+---+---+ |
3558 | | | ^ | | |
3559 | +---+---+---+ */ |
3560 | keyPresses = {Qt::Key_PageDown, Qt::Key_Right, Qt::Key_Up}; |
3561 | model = QSharedPointer<QStandardItemModel>::create(arguments: 3, arguments: 3); |
3562 | QTest::newRow(dataTag: "col span, bottom up #2" ) |
3563 | << keyPresses << model << 1 << 0 << 1 << 3 << model->index(row: 1, column: 1) << model->index(row: 1, column: 0); |
3564 | |
3565 | /* +---+---+---+ |
3566 | | | | v | |
3567 | +---+---+---+ |
3568 | | x c | |
3569 | +---+---+---+ |
3570 | | | | | |
3571 | +---+---+---+ */ |
3572 | keyPresses = {Qt::Key_End, Qt::Key_Down}; |
3573 | model = QSharedPointer<QStandardItemModel>::create(arguments: 3, arguments: 3); |
3574 | QTest::newRow(dataTag: "col span, top down" ) |
3575 | << keyPresses << model << 1 << 0 << 1 << 3 << model->index(row: 1, column: 2) << model->index(row: 1, column: 0); |
3576 | } |
3577 | |
3578 | class TableViewWithCursorExposed : public QTableView |
3579 | { |
3580 | public: |
3581 | using QTableView::QTableView; |
3582 | |
3583 | QModelIndex visualCursorIndex() |
3584 | { |
3585 | QTableViewPrivate *d = static_cast<QTableViewPrivate*>(qt_widget_private(widget: this)); |
3586 | return d->model->index(row: d->visualCursor.y(), column: d->visualCursor.x()); |
3587 | } |
3588 | }; |
3589 | |
3590 | void tst_QTableView::editSpanFromDirections() |
3591 | { |
3592 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
3593 | QSKIP("Wayland: This fails. Figure out why." ); |
3594 | |
3595 | QFETCH(const KeyList, keyPresses); |
3596 | QFETCH(QSharedPointer<QStandardItemModel>, model); |
3597 | QFETCH(int, row); |
3598 | QFETCH(int, column); |
3599 | QFETCH(int, rowSpan); |
3600 | QFETCH(int, columnSpan); |
3601 | QFETCH(QModelIndex, expectedVisualCursorIndex); |
3602 | QFETCH(QModelIndex, expectedEditedIndex); |
3603 | |
3604 | TableViewWithCursorExposed view; |
3605 | view.setModel(model.data()); |
3606 | // we have to make sure that PgUp/PgDown can scroll to the bottom/top |
3607 | view.resize(w: view.horizontalHeader()->length() + 50, |
3608 | h: view.verticalHeader()->length() + 50); |
3609 | view.setSpan(row, column, rowSpan, columnSpan); |
3610 | view.show(); |
3611 | QVERIFY(QTest::qWaitForWindowActive(&view)); |
3612 | |
3613 | for (Qt::Key key : keyPresses) |
3614 | QTest::keyClick(widget: &view, key); |
3615 | QCOMPARE(view.visualCursorIndex(), expectedVisualCursorIndex); |
3616 | QCOMPARE(view.selectionModel()->currentIndex(), expectedEditedIndex); |
3617 | |
3618 | QTest::keyClick(widget: &view, key: Qt::Key_X); |
3619 | QTest::keyClick(widget: QApplication::focusWidget(), key: Qt::Key_Enter); |
3620 | QTRY_COMPARE(view.model()->data(expectedEditedIndex).toString(), QLatin1String("x" )); |
3621 | } |
3622 | |
3623 | class Model : public QAbstractTableModel |
3624 | { |
3625 | Q_OBJECT |
3626 | public: |
3627 | using QAbstractTableModel::QAbstractTableModel; |
3628 | |
3629 | int rowCount(const QModelIndex &) const override |
3630 | { |
3631 | return rows; |
3632 | } |
3633 | int columnCount(const QModelIndex &) const override |
3634 | { |
3635 | return columns; |
3636 | } |
3637 | QVariant data(const QModelIndex &, int) const override |
3638 | { |
3639 | return QVariant(); |
3640 | } |
3641 | void res() |
3642 | { |
3643 | beginResetModel(); |
3644 | endResetModel(); |
3645 | } |
3646 | |
3647 | int rows = 0; |
3648 | int columns = 0; |
3649 | }; |
3650 | |
3651 | void tst_QTableView::() |
3652 | { |
3653 | QTableView view; |
3654 | Model m; |
3655 | m.rows = 3; |
3656 | m.columns = 3; |
3657 | view.setModel(&m); |
3658 | |
3659 | m.rows = 4; |
3660 | m.columns = 4; |
3661 | m.res(); |
3662 | QCOMPARE(view.horizontalHeader()->count(), 4); |
3663 | } |
3664 | |
3665 | void tst_QTableView::() |
3666 | { |
3667 | //tests if the minimumsize is of a header is taken into account |
3668 | //while computing QTableView geometry. For that we test the position of the |
3669 | //viewport. |
3670 | QTableView view; |
3671 | QStringListModel m; |
3672 | m.setStringList({QLatin1String("one cell is enough" )}); |
3673 | view.setModel(&m); |
3674 | |
3675 | //setting the minimum height on the horizontal header |
3676 | //and the minimum width on the vertical header |
3677 | view.horizontalHeader()->setMinimumHeight(50); |
3678 | view.verticalHeader()->setMinimumWidth(100); |
3679 | |
3680 | view.show(); |
3681 | |
3682 | QVERIFY( view.verticalHeader()->y() >= view.horizontalHeader()->minimumHeight()); |
3683 | QVERIFY( view.horizontalHeader()->x() >= view.verticalHeader()->minimumWidth()); |
3684 | } |
3685 | |
3686 | void tst_QTableView::resizeToContents() |
3687 | { |
3688 | //checks that the resize to contents is consistent |
3689 | QTableWidget table(2,3); |
3690 | QTableWidget table2(2,3); |
3691 | QTableWidget table3(2,3); |
3692 | |
3693 | |
3694 | table.setHorizontalHeaderItem(column: 0, item: new QTableWidgetItem("A Lot of text here: BLA BLA BLA" )); |
3695 | table2.setHorizontalHeaderItem(column: 0, item: new QTableWidgetItem("A Lot of text here: BLA BLA BLA" )); |
3696 | table3.setHorizontalHeaderItem(column: 0, item: new QTableWidgetItem("A Lot of text here: BLA BLA BLA" )); |
3697 | table.horizontalHeader()->setVisible(false); |
3698 | table2.horizontalHeader()->setVisible(false); |
3699 | table.verticalHeader()->setVisible(false); |
3700 | table2.verticalHeader()->setVisible(false); |
3701 | |
3702 | |
3703 | for (int i = 0; i < table.columnCount(); i++) |
3704 | table.resizeColumnToContents(column: i); |
3705 | for (int i = 0; i < table.rowCount(); i++) |
3706 | table.resizeRowToContents(row: i); |
3707 | table2.resizeColumnsToContents(); |
3708 | table2.resizeRowsToContents(); |
3709 | table3.resizeColumnsToContents(); |
3710 | table3.resizeRowsToContents(); |
3711 | |
3712 | //now let's check the row/col sizes |
3713 | for (int i = 0; i < table.columnCount(); i++) { |
3714 | QCOMPARE(table.columnWidth(i), table2.columnWidth(i)); |
3715 | QCOMPARE(table2.columnWidth(i), table3.columnWidth(i)); |
3716 | } |
3717 | for (int i = 0; i < table.rowCount(); i++) { |
3718 | QCOMPARE(table.rowHeight(i), table2.rowHeight(i)); |
3719 | QCOMPARE(table2.rowHeight(i), table3.rowHeight(i)); |
3720 | } |
3721 | |
3722 | } |
3723 | |
3724 | QT_BEGIN_NAMESPACE |
3725 | extern bool Q_WIDGETS_EXPORT qt_tab_all_widgets(); // qapplication.cpp |
3726 | QT_END_NAMESPACE |
3727 | |
3728 | void tst_QTableView::tabFocus() |
3729 | { |
3730 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
3731 | QSKIP("Wayland: This fails. Figure out why." ); |
3732 | |
3733 | if (!qt_tab_all_widgets()) |
3734 | QSKIP("This test requires full keyboard control to be enabled." ); |
3735 | |
3736 | // QTableView enables tabKeyNavigation by default, but you should be able |
3737 | // to change focus on an empty table view, or on a table view that doesn't |
3738 | // have this property set. |
3739 | QWidget window; |
3740 | window.resize(w: 200, h: 200); |
3741 | |
3742 | QTableView *view = new QTableView(&window); |
3743 | QLineEdit *edit = new QLineEdit(&window); |
3744 | |
3745 | window.show(); |
3746 | QApplication::setActiveWindow(&window); |
3747 | window.setFocus(); |
3748 | window.activateWindow(); |
3749 | QVERIFY(QTest::qWaitForWindowActive(&window)); |
3750 | |
3751 | // window |
3752 | QVERIFY(window.hasFocus()); |
3753 | QVERIFY(!view->hasFocus()); |
3754 | QVERIFY(!edit->hasFocus()); |
3755 | |
3756 | for (int i = 0; i < 2; ++i) { |
3757 | // tab to view |
3758 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Tab); |
3759 | QTRY_VERIFY(!window.hasFocus()); |
3760 | QVERIFY(view->hasFocus()); |
3761 | QVERIFY(!edit->hasFocus()); |
3762 | |
3763 | // tab to edit |
3764 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Tab); |
3765 | QTRY_VERIFY(edit->hasFocus()); |
3766 | QVERIFY(!window.hasFocus()); |
3767 | QVERIFY(!view->hasFocus()); |
3768 | } |
3769 | |
3770 | // backtab to view |
3771 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3772 | QTRY_VERIFY(view->hasFocus()); |
3773 | QVERIFY(!window.hasFocus()); |
3774 | QVERIFY(!edit->hasFocus()); |
3775 | |
3776 | // backtab to edit |
3777 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3778 | QTRY_VERIFY(edit->hasFocus()); |
3779 | QVERIFY(!window.hasFocus()); |
3780 | QVERIFY(!view->hasFocus()); |
3781 | |
3782 | QStandardItemModel model; |
3783 | view->setModel(&model); |
3784 | |
3785 | // backtab to view |
3786 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3787 | QTRY_VERIFY(view->hasFocus()); |
3788 | QVERIFY(!window.hasFocus()); |
3789 | QVERIFY(!edit->hasFocus()); |
3790 | |
3791 | // backtab to edit |
3792 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3793 | QTRY_VERIFY(edit->hasFocus()); |
3794 | QVERIFY(!window.hasFocus()); |
3795 | QVERIFY(!view->hasFocus()); |
3796 | |
3797 | model.insertRow(arow: 0, aitem: new QStandardItem("Hei" )); |
3798 | model.insertRow(arow: 0, aitem: new QStandardItem("Hei" )); |
3799 | model.insertRow(arow: 0, aitem: new QStandardItem("Hei" )); |
3800 | |
3801 | // backtab to view |
3802 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3803 | QTRY_VERIFY(view->hasFocus()); |
3804 | QVERIFY(!window.hasFocus()); |
3805 | QVERIFY(!edit->hasFocus()); |
3806 | |
3807 | // backtab to edit doesn't work |
3808 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3809 | QVERIFY(!window.hasFocus()); |
3810 | QVERIFY(view->hasFocus()); |
3811 | QVERIFY(!edit->hasFocus()); |
3812 | |
3813 | view->setTabKeyNavigation(false); |
3814 | |
3815 | // backtab to edit |
3816 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Backtab); |
3817 | QTRY_VERIFY(edit->hasFocus()); |
3818 | QVERIFY(!window.hasFocus()); |
3819 | QVERIFY(!view->hasFocus()); |
3820 | |
3821 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Tab); |
3822 | QTRY_VERIFY(view->hasFocus()); |
3823 | QTest::keyPress(widget: QApplication::focusWidget(), key: Qt::Key_Tab); |
3824 | QTRY_VERIFY(edit->hasFocus()); |
3825 | } |
3826 | |
3827 | class BigModel : public QAbstractTableModel |
3828 | { |
3829 | Q_OBJECT |
3830 | public: |
3831 | QVariant data(const QModelIndex &index, |
3832 | int role = Qt::DisplayRole) const override |
3833 | { |
3834 | if (role == Qt::DisplayRole) |
3835 | return QString::number(index.column()) + QLatin1String(" - " ) + QString::number(index.row()); |
3836 | return QVariant(); |
3837 | } |
3838 | |
3839 | int rowCount(const QModelIndex &parent = QModelIndex()) const override |
3840 | { |
3841 | Q_UNUSED(parent) |
3842 | return 10000000; |
3843 | } |
3844 | |
3845 | int columnCount(const QModelIndex &parent = QModelIndex()) const override |
3846 | { |
3847 | Q_UNUSED(parent) |
3848 | return 20000000; |
3849 | } |
3850 | }; |
3851 | |
3852 | void tst_QTableView::bigModel() |
3853 | { |
3854 | //should not crash |
3855 | QTableView view; |
3856 | BigModel model; |
3857 | view.setModel(&model); |
3858 | view.show(); |
3859 | view.setSpan(row: 10002,column: 10002,rowSpan: 6,columnSpan: 6); |
3860 | QTest::qWait(ms: 100); |
3861 | view.resize(w: 1000,h: 1000); |
3862 | QTest::qWait(ms: 100); |
3863 | view.scrollTo(index: model.index(row: 10010,column: 10010)); |
3864 | QTest::qWait(ms: 100); |
3865 | } |
3866 | |
3867 | void tst_QTableView::selectionSignal() |
3868 | { |
3869 | QtTestTableModel model(10, 10); |
3870 | QtTestTableView view; |
3871 | view.checkSignalOrder = true; |
3872 | view.setModel(&model); |
3873 | view.resize(w: 200, h: 200); |
3874 | view.show(); |
3875 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
3876 | QTest::mouseClick(widget: view.viewport(), button: Qt::LeftButton, stateKey: {}, pos: view.visualRect(index: model.index(row: 2, column: 0)).center()); |
3877 | } |
3878 | |
3879 | void tst_QTableView::setCurrentIndex() |
3880 | { |
3881 | QtTestTableModel model(4, 4); |
3882 | QtTestTableView view; |
3883 | view.setModel(&model); |
3884 | |
3885 | // submit() slot should be called in model when current row changes |
3886 | view.setCurrentIndex(model.index(row: 0,column: 0)); |
3887 | QCOMPARE(model.submit_count, 1); |
3888 | view.setCurrentIndex(model.index(row: 0,column: 2)); |
3889 | QCOMPARE(model.submit_count, 1); |
3890 | view.setCurrentIndex(model.index(row: 1,column: 0)); |
3891 | QCOMPARE(model.submit_count, 2); |
3892 | view.setCurrentIndex(model.index(row: 3,column: 3)); |
3893 | QCOMPARE(model.submit_count, 3); |
3894 | view.setCurrentIndex(model.index(row: 0,column: 1)); |
3895 | QCOMPARE(model.submit_count, 4); |
3896 | view.setCurrentIndex(model.index(row: 0,column: 0)); |
3897 | QCOMPARE(model.submit_count, 4); |
3898 | } |
3899 | |
3900 | class task173773_EventFilter : public QObject |
3901 | { |
3902 | int paintEventCount_ = 0; |
3903 | public: |
3904 | using QObject::QObject; |
3905 | int paintEventCount() const { return paintEventCount_; } |
3906 | private: |
3907 | bool eventFilter(QObject *obj, QEvent *e) override |
3908 | { |
3909 | Q_UNUSED(obj) |
3910 | if (e->type() == QEvent::Paint) |
3911 | ++paintEventCount_; |
3912 | return false; |
3913 | } |
3914 | }; |
3915 | |
3916 | void tst_QTableView::() |
3917 | { |
3918 | QStandardItemModel model(2, 1); |
3919 | model.setData(index: model.index(row: 0, column: 0), value: 0); |
3920 | model.setData(index: model.index(row: 1, column: 0), value: 1); |
3921 | |
3922 | QSortFilterProxyModel proxyModel; |
3923 | proxyModel.setSourceModel(&model); |
3924 | |
3925 | QTableView view; |
3926 | view.setModel(&proxyModel); |
3927 | view.setSortingEnabled(true); |
3928 | view.show(); |
3929 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
3930 | |
3931 | view.sortByColumn(column: 0, order: Qt::AscendingOrder); |
3932 | QTest::qWait(ms: 100); |
3933 | |
3934 | task173773_EventFilter eventFilter; |
3935 | view.verticalHeader()->viewport()->installEventFilter(filterObj: &eventFilter); |
3936 | |
3937 | view.sortByColumn(column: 0, order: Qt::DescendingOrder); |
3938 | QTest::qWait(ms: 100); |
3939 | |
3940 | // ### note: this test may occasionally pass even if the bug is present! |
3941 | QVERIFY(eventFilter.paintEventCount() > 0); |
3942 | } |
3943 | |
3944 | void tst_QTableView::task227953_setRootIndex() |
3945 | { |
3946 | QTableView tableView; |
3947 | |
3948 | //model = tree with two items with tables as children |
3949 | QStandardItemModel model; |
3950 | QStandardItem item1, item2; |
3951 | model.appendColumn(items: QList<QStandardItem*>() << &item1 << &item2); |
3952 | |
3953 | |
3954 | //setup the first table as a child of the first item |
3955 | for ( int row = 0; row < 40; ++row ) { |
3956 | item1.appendRow(aitems: QList<QStandardItem*>() << new QStandardItem(QLatin1String("row " ) + QString::number(row))); |
3957 | } |
3958 | |
3959 | //setup the second table as a child of the second item |
3960 | for ( int row = 0; row < 10; ++row ) { |
3961 | item2.appendRow(aitems: QList<QStandardItem*>() << new QStandardItem(QLatin1String("row " ) + QString::number(row))); |
3962 | } |
3963 | |
3964 | tableView.setModel(&model); |
3965 | |
3966 | //show the first 10 rows of the first table |
3967 | QModelIndex root = model.indexFromItem(item: &item1); |
3968 | tableView.setRootIndex(root); |
3969 | for (int i = 10; i != 40; ++i) { |
3970 | tableView.setRowHidden(row: i, hide: true); |
3971 | } |
3972 | |
3973 | QCOMPARE(tableView.verticalHeader()->count(), 40); |
3974 | QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 30); |
3975 | |
3976 | //show the first 10 rows of the second table |
3977 | tableView.setRootIndex(model.indexFromItem(item: &item2)); |
3978 | |
3979 | QCOMPARE(tableView.verticalHeader()->count(), 10); |
3980 | QCOMPARE(tableView.verticalHeader()->hiddenSectionCount(), 0); |
3981 | QVERIFY(!tableView.verticalHeader()->isHidden()); |
3982 | } |
3983 | |
3984 | void tst_QTableView::task240266_veryBigColumn() |
3985 | { |
3986 | QTableView table; |
3987 | table.setFixedSize(w: 500, h: 300); //just to make sure we have the 2 first columns visible |
3988 | QStandardItemModel model(1, 3); |
3989 | table.setModel(&model); |
3990 | table.setColumnWidth(column: 0, width: 100); //normal column |
3991 | table.setColumnWidth(column: 1, width: 100); //normal column |
3992 | table.setColumnWidth(column: 2, width: 9000); //very big column |
3993 | table.show(); |
3994 | QVERIFY(QTest::qWaitForWindowExposed(&table)); |
3995 | |
3996 | //some styles change the scroll mode in their polish |
3997 | table.setHorizontalScrollMode(QAbstractItemView::ScrollPerItem); |
3998 | table.setVerticalScrollMode(QAbstractItemView::ScrollPerItem); |
3999 | |
4000 | QScrollBar *scroll = table.horizontalScrollBar(); |
4001 | QCOMPARE(scroll->minimum(), 0); |
4002 | QCOMPARE(scroll->maximum(), model.columnCount() - 1); |
4003 | QCOMPARE(scroll->singleStep(), 1); |
4004 | |
4005 | //1 is not always a very correct value for pageStep. Ideally this should be dynamic. |
4006 | //Maybe something for Qt 5 ;-) |
4007 | QCOMPARE(scroll->pageStep(), 1); |
4008 | |
4009 | } |
4010 | |
4011 | void tst_QTableView::task248688_autoScrollNavigation() |
4012 | { |
4013 | //we make sure that when navigating with the keyboard the view is correctly scrolled |
4014 | //to the current item |
4015 | QStandardItemModel model(16, 16); |
4016 | QTableView view; |
4017 | view.setModel(&model); |
4018 | |
4019 | view.hideColumn(column: 8); |
4020 | view.hideRow(row: 8); |
4021 | view.show(); |
4022 | for (int r = 0; r < model.rowCount(); ++r) { |
4023 | if (view.isRowHidden(row: r)) |
4024 | continue; |
4025 | for (int c = 0; c < model.columnCount(); ++c) { |
4026 | if (view.isColumnHidden(column: c)) |
4027 | continue; |
4028 | QModelIndex index = model.index(row: r, column: c); |
4029 | view.setCurrentIndex(index); |
4030 | QVERIFY(view.viewport()->rect().contains(view.visualRect(index))); |
4031 | } |
4032 | } |
4033 | } |
4034 | |
4035 | #if QT_CONFIG(wheelevent) |
4036 | void tst_QTableView::mouseWheel_data() |
4037 | { |
4038 | QTest::addColumn<QAbstractItemView::ScrollMode>(name: "scrollMode" ); |
4039 | QTest::addColumn<int>(name: "delta" ); |
4040 | QTest::addColumn<int>(name: "horizontalPositon" ); |
4041 | QTest::addColumn<int>(name: "verticalPosition" ); |
4042 | |
4043 | QTest::newRow(dataTag: "scroll up per item" ) |
4044 | << QAbstractItemView::ScrollPerItem << 120 |
4045 | << 10 - QApplication::wheelScrollLines() << 10 - QApplication::wheelScrollLines(); |
4046 | QTest::newRow(dataTag: "scroll down per item" ) |
4047 | << QAbstractItemView::ScrollPerItem << -120 |
4048 | << 10 + QApplication::wheelScrollLines() << 10 + QApplication::wheelScrollLines(); |
4049 | QTest::newRow(dataTag: "scroll down per pixel" ) |
4050 | << QAbstractItemView::ScrollPerPixel << -120 |
4051 | << 10 + QApplication::wheelScrollLines() * 91 << 10 + QApplication::wheelScrollLines() * 46; |
4052 | } |
4053 | |
4054 | void tst_QTableView::mouseWheel() |
4055 | { |
4056 | QFETCH(QAbstractItemView::ScrollMode, scrollMode); |
4057 | QFETCH(int, delta); |
4058 | QFETCH(int, horizontalPositon); |
4059 | QFETCH(int, verticalPosition); |
4060 | |
4061 | QtTestTableModel model(100, 100); |
4062 | QWidget topLevel; |
4063 | QtTestTableView view(&topLevel); |
4064 | view.resize(w: 500, h: 500); |
4065 | topLevel.show(); |
4066 | |
4067 | QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); |
4068 | |
4069 | view.setModel(&model); |
4070 | |
4071 | for (int r = 0; r < 100; ++r) |
4072 | view.setRowHeight(row: r, height: 50); |
4073 | for (int c = 0; c < 100; ++c) |
4074 | view.setColumnWidth(column: c, width: 100); |
4075 | |
4076 | view.setHorizontalScrollMode(scrollMode); |
4077 | view.setVerticalScrollMode(scrollMode); |
4078 | view.horizontalScrollBar()->setValue(10); |
4079 | view.verticalScrollBar()->setValue(10); |
4080 | |
4081 | QPoint pos = view.viewport()->geometry().center(); |
4082 | QWheelEvent verticalEvent(pos, view.mapToGlobal(pos), QPoint(), QPoint(0, delta), |
4083 | Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); |
4084 | QWheelEvent horizontalEvent(pos, view.mapToGlobal(pos), QPoint(), QPoint(delta, 0), |
4085 | Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); |
4086 | QApplication::sendEvent(receiver: view.viewport(), event: &horizontalEvent); |
4087 | QVERIFY(qAbs(view.horizontalScrollBar()->value() - horizontalPositon) < 15); |
4088 | QApplication::sendEvent(receiver: view.viewport(), event: &verticalEvent); |
4089 | QVERIFY(qAbs(view.verticalScrollBar()->value() - verticalPosition) < 15); |
4090 | } |
4091 | #endif // QT_CONFIG(wheelevent) |
4092 | |
4093 | void tst_QTableView::addColumnWhileEditing() |
4094 | { |
4095 | QTableView view; |
4096 | QStandardItemModel model(1, 10); |
4097 | view.setModel(&model); |
4098 | QModelIndex last = model.index(row: 0,column: 9); |
4099 | view.show(); |
4100 | |
4101 | view.openPersistentEditor(index: last); |
4102 | view.scrollTo(index: last); |
4103 | |
4104 | //let's see if the editor is moved to the right location |
4105 | //after adding a column |
4106 | model.setColumnCount(model.columnCount() + 1); |
4107 | QPointer<QLineEdit> editor = view.findChild<QLineEdit*>(); |
4108 | QVERIFY(editor); |
4109 | QCOMPARE(editor->geometry(), view.visualRect(last)); |
4110 | |
4111 | //let's see if the editor is moved to the right location |
4112 | //after removing a column |
4113 | view.scrollTo(index: model.index(row: 0, column: model.columnCount()-1)); |
4114 | model.setColumnCount(model.columnCount() - 1); |
4115 | QVERIFY(editor); |
4116 | QCOMPARE(editor->geometry(), view.visualRect(last)); |
4117 | } |
4118 | |
4119 | void tst_QTableView::() |
4120 | { |
4121 | QStandardItemModel model; |
4122 | model.setRowCount(50); |
4123 | model.setColumnCount(2); |
4124 | for (int row = 0; row < model.rowCount(); ++row) |
4125 | for (int col = 0; col < model.columnCount(); ++col) { |
4126 | const QModelIndex &idx = model.index(row, column: col); |
4127 | model.setData(index: idx, value: QVariant(row), role: Qt::EditRole); |
4128 | } |
4129 | |
4130 | QTableView tv; |
4131 | tv.setModel(&model); |
4132 | tv.show(); |
4133 | tv.verticalHeader()->swapSections(first: 0, second: model.rowCount() - 1); |
4134 | tv.setCurrentIndex(model.index(row: model.rowCount() - 1, column: 0)); |
4135 | |
4136 | QVERIFY(QTest::qWaitForWindowExposed(&tv)); |
4137 | QTest::keyClick(widget: &tv, key: Qt::Key_PageUp); // PageUp won't scroll when at top |
4138 | QTRY_COMPARE(tv.rowAt(0), tv.verticalHeader()->logicalIndex(0)); |
4139 | |
4140 | int newRow = tv.rowAt(y: tv.viewport()->height()); |
4141 | QTest::keyClick(widget: &tv, key: Qt::Key_PageDown); // Scroll down and check current |
4142 | QTRY_COMPARE(tv.currentIndex().row(), newRow); |
4143 | |
4144 | tv.setCurrentIndex(model.index(row: 0, column: 0)); |
4145 | QTest::keyClick(widget: &tv, key: Qt::Key_PageDown); // PageDown won't scroll when at the bottom |
4146 | QTRY_COMPARE(tv.rowAt(tv.viewport()->height() - 1), tv.verticalHeader()->logicalIndex(model.rowCount() - 1)); |
4147 | } |
4148 | |
4149 | template <typename T> |
4150 | struct ValueSaver { |
4151 | T &var, value; |
4152 | ValueSaver(T &v) : var(v), value(v) { } |
4153 | ~ValueSaver() { var = value; } |
4154 | }; |
4155 | |
4156 | void tst_QTableView::task191545_dragSelectRows() |
4157 | { |
4158 | if (QGuiApplication::platformName().startsWith(s: QLatin1String("wayland" ), cs: Qt::CaseInsensitive)) |
4159 | QSKIP("Wayland: This fails. Figure out why." ); |
4160 | |
4161 | QStandardItemModel model(10, 10); |
4162 | QTableView table; |
4163 | table.setModel(&model); |
4164 | table.setSelectionBehavior(QAbstractItemView::SelectItems); |
4165 | table.setSelectionMode(QAbstractItemView::ExtendedSelection); |
4166 | table.setMinimumSize(minw: 1000, minh: 400); |
4167 | table.show(); |
4168 | QVERIFY(QTest::qWaitForWindowActive(&table)); |
4169 | |
4170 | ValueSaver<Qt::KeyboardModifiers> saver(QApplicationPrivate::modifier_buttons); |
4171 | QApplicationPrivate::modifier_buttons = Qt::ControlModifier; |
4172 | |
4173 | { |
4174 | QRect cellRect = table.visualRect(index: model.index(row: 3, column: 0)); |
4175 | QHeaderView * = table.verticalHeader(); |
4176 | QWidget * = vHeader->viewport(); |
4177 | QPoint rowPos(cellRect.center()); |
4178 | QMouseEvent rowPressEvent(QEvent::MouseButtonPress, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4179 | QCoreApplication::sendEvent(receiver: vHeaderVp, event: &rowPressEvent); |
4180 | |
4181 | for (int i = 0; i < 4; ++i) { |
4182 | rowPos.setY(rowPos.y() + cellRect.height()); |
4183 | QMouseEvent moveEvent(QEvent::MouseMove, rowPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier); |
4184 | QCoreApplication::sendEvent(receiver: vHeaderVp, event: &moveEvent); |
4185 | } |
4186 | QMouseEvent rowReleaseEvent(QEvent::MouseButtonRelease, rowPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4187 | QCoreApplication::sendEvent(receiver: vHeaderVp, event: &rowReleaseEvent); |
4188 | |
4189 | for (int i = 0; i < 4; ++i) { |
4190 | QModelIndex index = model.index(row: 3 + i, column: 0, parent: table.rootIndex()); |
4191 | QVERIFY(vHeader->selectionModel()->selectedRows().contains(index)); |
4192 | } |
4193 | } |
4194 | |
4195 | { |
4196 | QRect cellRect = table.visualRect(index: model.index(row: 0, column: 3)); |
4197 | QHeaderView * = table.horizontalHeader(); |
4198 | QWidget * = hHeader->viewport(); |
4199 | QPoint colPos((cellRect.left() + cellRect.right()) / 2, 5); |
4200 | QMouseEvent colPressEvent(QEvent::MouseButtonPress, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4201 | QCoreApplication::sendEvent(receiver: hHeaderVp, event: &colPressEvent); |
4202 | |
4203 | for (int i = 0; i < 4; ++i) { |
4204 | colPos.setX(colPos.x() + cellRect.width()); |
4205 | QMouseEvent moveEvent(QEvent::MouseMove, colPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier); |
4206 | QCoreApplication::sendEvent(receiver: hHeaderVp, event: &moveEvent); |
4207 | } |
4208 | QMouseEvent colReleaseEvent(QEvent::MouseButtonRelease, colPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4209 | QCoreApplication::sendEvent(receiver: hHeaderVp, event: &colReleaseEvent); |
4210 | |
4211 | for (int i = 0; i < 4; ++i) { |
4212 | QModelIndex index = model.index(row: 0, column: 3 + i, parent: table.rootIndex()); |
4213 | QVERIFY(hHeader->selectionModel()->selectedColumns().contains(index)); |
4214 | } |
4215 | } |
4216 | |
4217 | { |
4218 | QRect cellRect = table.visualRect(index: model.index(row: 2, column: 2)); |
4219 | QWidget *tableVp = table.viewport(); |
4220 | QPoint cellPos = cellRect.center(); |
4221 | QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4222 | QCoreApplication::sendEvent(receiver: tableVp, event: &cellPressEvent); |
4223 | |
4224 | for (int i = 0; i < 6; ++i) { |
4225 | cellPos.setX(cellPos.x() + cellRect.width()); |
4226 | cellPos.setY(cellPos.y() + cellRect.height()); |
4227 | QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier); |
4228 | QCoreApplication::sendEvent(receiver: tableVp, event: &moveEvent); |
4229 | } |
4230 | QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4231 | QCoreApplication::sendEvent(receiver: tableVp, event: &cellReleaseEvent); |
4232 | |
4233 | for (int i = 0; i < 6; ++i) { |
4234 | for (int j = 0; j < 6; ++j) { |
4235 | QModelIndex index = model.index(row: 2 + i, column: 2 + j, parent: table.rootIndex()); |
4236 | QVERIFY(table.selectionModel()->isSelected(index)); |
4237 | } |
4238 | } |
4239 | } |
4240 | |
4241 | { |
4242 | QRect cellRect = table.visualRect(index: model.index(row: 3, column: 3)); |
4243 | QWidget *tableVp = table.viewport(); |
4244 | QPoint cellPos = cellRect.center(); |
4245 | QMouseEvent cellPressEvent(QEvent::MouseButtonPress, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4246 | QCoreApplication::sendEvent(receiver: tableVp, event: &cellPressEvent); |
4247 | |
4248 | for (int i = 0; i < 6; ++i) { |
4249 | cellPos.setX(cellPos.x() + cellRect.width()); |
4250 | cellPos.setY(cellPos.y() + cellRect.height()); |
4251 | QMouseEvent moveEvent(QEvent::MouseMove, cellPos, Qt::NoButton, Qt::LeftButton, Qt::ControlModifier); |
4252 | QCoreApplication::sendEvent(receiver: tableVp, event: &moveEvent); |
4253 | } |
4254 | QMouseEvent cellReleaseEvent(QEvent::MouseButtonRelease, cellPos, Qt::LeftButton, Qt::NoButton, Qt::ControlModifier); |
4255 | QCoreApplication::sendEvent(receiver: tableVp, event: &cellReleaseEvent); |
4256 | |
4257 | QTest::qWait(ms: 200); |
4258 | for (int i = 0; i < 6; ++i) { |
4259 | for (int j = 0; j < 6; ++j) { |
4260 | QModelIndex index = model.index(row: 3 + i, column: 3 + j, parent: table.rootIndex()); |
4261 | QVERIFY(!table.selectionModel()->isSelected(index)); |
4262 | } |
4263 | } |
4264 | } |
4265 | } |
4266 | |
4267 | void tst_QTableView::() |
4268 | { |
4269 | QStringListModel model; |
4270 | QSortFilterProxyModel sfpm; // default QStandardItemModel does not support 'unsorted' state |
4271 | sfpm.setSourceModel(&model); |
4272 | const QStringList data({"orange" , "apple" , "banana" , "lemon" , "pumpkin" }); |
4273 | QStringList sortedDataA = data; |
4274 | QStringList sortedDataD = data; |
4275 | std::sort(first: sortedDataA.begin(), last: sortedDataA.end()); |
4276 | std::sort(first: sortedDataD.begin(), last: sortedDataD.end(), comp: std::greater<QString>()); |
4277 | model.setStringList(data); |
4278 | QTableView view; |
4279 | view.setModel(&sfpm); |
4280 | |
4281 | QTRY_COMPARE(model.stringList(), data); |
4282 | view.setSortingEnabled(true); |
4283 | view.sortByColumn(column: 0, order: Qt::AscendingOrder); |
4284 | for (int i = 0; i < sortedDataA.size(); ++i) |
4285 | QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataA.at(i)); |
4286 | |
4287 | view.horizontalHeader()->setSortIndicator(logicalIndex: 0, order: Qt::DescendingOrder); |
4288 | for (int i = 0; i < sortedDataD.size(); ++i) |
4289 | QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataD.at(i)); |
4290 | |
4291 | QHeaderView *h = new QHeaderView(Qt::Horizontal); |
4292 | h->setModel(&model); |
4293 | view.setHorizontalHeader(h); |
4294 | h->setSortIndicator(logicalIndex: 0, order: Qt::AscendingOrder); |
4295 | for (int i = 0; i < sortedDataA.size(); ++i) |
4296 | QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataA.at(i)); |
4297 | |
4298 | h->setSortIndicator(logicalIndex: 0, order: Qt::DescendingOrder); |
4299 | for (int i = 0; i < sortedDataD.size(); ++i) |
4300 | QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), sortedDataD.at(i)); |
4301 | |
4302 | view.sortByColumn(column: -1, order: Qt::AscendingOrder); |
4303 | QCOMPARE(view.horizontalHeader()->sortIndicatorSection(), -1); |
4304 | for (int i = 0; i < data.size(); ++i) |
4305 | QCOMPARE(view.model()->data(view.model()->index(i, 0)).toString(), data.at(i)); |
4306 | } |
4307 | |
4308 | void tst_QTableView::taskQTBUG_5062_spansInconsistency() |
4309 | { |
4310 | const int nRows = 5; |
4311 | const int nColumns = 5; |
4312 | |
4313 | QtTestTableModel model(nRows, nColumns); |
4314 | QtTestTableView view; |
4315 | view.setModel(&model); |
4316 | |
4317 | for (int i = 0; i < nRows; ++i) |
4318 | view.setSpan(row: i, column: 0, rowSpan: 1, columnSpan: nColumns); |
4319 | view.setSpan(row: 2, column: 0, rowSpan: 1, columnSpan: 1); |
4320 | view.setSpan(row: 3, column: 0, rowSpan: 1, columnSpan: 1); |
4321 | |
4322 | VERIFY_SPANS_CONSISTENCY(&view); |
4323 | } |
4324 | |
4325 | void tst_QTableView::taskQTBUG_4516_clickOnRichTextLabel() |
4326 | { |
4327 | QTableView view; |
4328 | QStandardItemModel model(5,5); |
4329 | view.setModel(&model); |
4330 | QLabel label("rich text" ); |
4331 | label.setTextFormat(Qt::RichText); |
4332 | view.setIndexWidget(index: model.index(row: 1,column: 1), widget: &label); |
4333 | view.show(); |
4334 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
4335 | |
4336 | view.setCurrentIndex(model.index(row: 0,column: 0)); |
4337 | QCOMPARE(view.currentIndex(), model.index(0,0)); |
4338 | |
4339 | QTest::mouseClick(widget: &label, button: Qt::LeftButton); |
4340 | QCOMPARE(view.currentIndex(), model.index(1,1)); |
4341 | } |
4342 | |
4343 | |
4344 | void tst_QTableView::() |
4345 | { |
4346 | QTableView view; |
4347 | QStandardItemModel model(5,5); |
4348 | view.setModel(&model); |
4349 | view.show(); |
4350 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
4351 | |
4352 | QString text = "long long long text" ; |
4353 | const int textWidth = view.verticalHeader()->fontMetrics().horizontalAdvance(text); |
4354 | QVERIFY(view.verticalHeader()->width() < textWidth); |
4355 | |
4356 | model.setHeaderData(section: 2, orientation: Qt::Vertical, value: text); |
4357 | |
4358 | QTRY_VERIFY(view.verticalHeader()->width() > textWidth); |
4359 | } |
4360 | |
4361 | #if QT_CONFIG(wheelevent) |
4362 | void tst_QTableView::() |
4363 | { |
4364 | QTableView view; |
4365 | QStandardItemModel model(500,5); |
4366 | view.setModel(&model); |
4367 | view.show(); |
4368 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
4369 | |
4370 | int sbValueBefore = view.verticalScrollBar()->value(); |
4371 | QHeaderView * = view.verticalHeader(); |
4372 | QTest::mouseMove(widget: header); |
4373 | QPoint pos = header->geometry().center(); |
4374 | QWheelEvent wheelEvent(pos, header->viewport()->mapToGlobal(pos), QPoint(), QPoint(0, -720), |
4375 | Qt::NoButton, Qt::NoModifier, Qt::NoScrollPhase, false); |
4376 | QApplication::sendEvent(receiver: header->viewport(), event: &wheelEvent); |
4377 | int sbValueAfter = view.verticalScrollBar()->value(); |
4378 | QVERIFY(sbValueBefore != sbValueAfter); |
4379 | } |
4380 | #endif |
4381 | |
4382 | class TestTableView : public QTableView |
4383 | { |
4384 | Q_OBJECT |
4385 | public: |
4386 | TestTableView(QWidget *parent = nullptr) : QTableView(parent) |
4387 | { |
4388 | connect(sender: this, signal: &QTableView::entered, receiver: this, slot: &TestTableView::openPersistentEditor); |
4389 | } |
4390 | public slots: |
4391 | void onDataChanged() |
4392 | { |
4393 | for (int i = 0; i < model()->rowCount(); i++) { |
4394 | setRowHidden(row: i, hide: model()->data(index: model()->index(row: i, column: 0)).toBool()); |
4395 | } |
4396 | } |
4397 | }; |
4398 | |
4399 | |
4400 | void tst_QTableView::taskQTBUG_8585_crashForNoGoodReason() |
4401 | { |
4402 | QStandardItemModel model; |
4403 | model.insertColumn(acolumn: 0, aparent: QModelIndex()); |
4404 | for (int i = 0; i < 20; i++) |
4405 | model.insertRow(arow: i); |
4406 | |
4407 | TestTableView w; |
4408 | w.setMouseTracking(true); |
4409 | w.setModel(&model); |
4410 | connect(sender: &model, signal: &QStandardItemModel::dataChanged, receiver: &w, slot: &TestTableView::onDataChanged); |
4411 | w.show(); |
4412 | QVERIFY(QTest::qWaitForWindowExposed(&w)); |
4413 | for (int i = 0; i < 10; i++) |
4414 | { |
4415 | QTest::mouseMove(widget: w.viewport(), pos: QPoint(50, 20)); |
4416 | w.model()->setData(index: w.indexAt(p: QPoint(50, 20)), value: true); |
4417 | QTest::mouseMove(widget: w.viewport(), pos: QPoint(50, 25)); |
4418 | } |
4419 | } |
4420 | |
4421 | class TableView7774 : public QTableView |
4422 | { |
4423 | public: |
4424 | using QTableView::visualRegionForSelection; |
4425 | }; |
4426 | |
4427 | void tst_QTableView::taskQTBUG_7774_RtoLVisualRegionForSelection() |
4428 | { |
4429 | TableView7774 view; |
4430 | QStandardItemModel model(5,5); |
4431 | view.setModel(&model); |
4432 | view.setLayoutDirection(Qt::RightToLeft); |
4433 | view.show(); |
4434 | QVERIFY(QTest::qWaitForWindowExposed(&view)); |
4435 | |
4436 | QItemSelectionRange range(model.index(row: 2, column: 0), model.index(row: 2, column: model.columnCount() - 1)); |
4437 | QItemSelection selection; |
4438 | selection << range; |
4439 | QRegion region = view.visualRegionForSelection(selection); |
4440 | QVERIFY(!region.isEmpty()); |
4441 | QCOMPARE(region.begin()[0], view.visualRect(range.topLeft()) | view.visualRect(range.bottomRight())); |
4442 | } |
4443 | |
4444 | void tst_QTableView::taskQTBUG_8777_scrollToSpans() |
4445 | { |
4446 | QTableWidget table(75,5); |
4447 | for (int i=0; i<50; i++) |
4448 | table.setSpan(row: 2+i, column: 0, rowSpan: 1, columnSpan: 5); |
4449 | table.setCurrentCell(row: 0,column: 2); |
4450 | table.show(); |
4451 | |
4452 | for (int i = 0; i < 45; ++i) |
4453 | QTest::keyClick(widget: &table, key: Qt::Key_Down); |
4454 | |
4455 | QVERIFY(table.verticalScrollBar()->value() > 10); |
4456 | } |
4457 | |
4458 | void tst_QTableView::taskQTBUG_10169_sizeHintForRow() |
4459 | { |
4460 | QtTestTableView tableView; |
4461 | QStandardItemModel model(1, 3); |
4462 | model.setData(index: model.index(row: 0, column: 0), value: "Word wrapping text goes here." ); |
4463 | tableView.setModel(&model); |
4464 | tableView.verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); |
4465 | const int orderedHeight = tableView.sizeHintForRow(row: 0); |
4466 | tableView.horizontalHeader()->moveSection(from: 2, to: 0); |
4467 | const int reorderedHeight = tableView.sizeHintForRow(row: 0); |
4468 | |
4469 | //the order of the columns shouldn't matter. |
4470 | QCOMPARE(orderedHeight, reorderedHeight); |
4471 | } |
4472 | |
4473 | void tst_QTableView::viewOptions() |
4474 | { |
4475 | QtTestTableView view; |
4476 | QStyleOptionViewItem options = view.viewOptions(); |
4477 | QVERIFY(options.showDecorationSelected); |
4478 | } |
4479 | |
4480 | void tst_QTableView::taskQTBUG_30653_doItemsLayout() |
4481 | { |
4482 | QWidget topLevel; |
4483 | QtTestTableView view(&topLevel); |
4484 | |
4485 | QtTestTableModel model(5, 5); |
4486 | view.setModel(&model); |
4487 | |
4488 | QtTestItemDelegate delegate; |
4489 | delegate.hint = QSize(50, 50); |
4490 | view.setItemDelegate(&delegate); |
4491 | |
4492 | view.resizeRowsToContents(); |
4493 | view.resizeColumnsToContents(); |
4494 | |
4495 | // show two and half rows/cols |
4496 | int = view.verticalHeader()->sizeHint().width() + view.verticalScrollBar()->sizeHint().width(); |
4497 | int = view.horizontalHeader()->sizeHint().height() + view.horizontalScrollBar()->sizeHint().height(); |
4498 | view.resize(w: 125 + extraWidth, h: 125 + extraHeight); |
4499 | |
4500 | topLevel.show(); |
4501 | QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); |
4502 | |
4503 | // the offset after scrollToBottom() and doItemsLayout() should not differ |
4504 | // as the view content should stay aligned to the last section |
4505 | view.scrollToBottom(); |
4506 | int scrollToBottomOffset = view.verticalHeader()->offset(); |
4507 | view.doItemsLayout(); |
4508 | int doItemsLayoutOffset = view.verticalHeader()->offset(); |
4509 | |
4510 | QCOMPARE(scrollToBottomOffset, doItemsLayoutOffset); |
4511 | } |
4512 | |
4513 | void tst_QTableView::taskQTBUG_7232_AllowUserToControlSingleStep() |
4514 | { |
4515 | // When we set the scrollMode to ScrollPerPixel it will adjust the scrollbars singleStep automatically |
4516 | // Setting a singlestep on a scrollbar should however imply that the user takes control (and it is not changed by geometry updates). |
4517 | // Setting a singlestep to -1 return to an automatic control of the singleStep. |
4518 | QTableView t; |
4519 | t.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); |
4520 | t.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); |
4521 | QStandardItemModel model(200, 200); |
4522 | t.setModel(&model); |
4523 | t.show(); |
4524 | QVERIFY(QTest::qWaitForWindowExposed(&t)); |
4525 | t.setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); |
4526 | t.setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); |
4527 | |
4528 | t.setGeometry(ax: 200, ay: 200, aw: 200, ah: 200); |
4529 | int vStep1 = t.verticalScrollBar()->singleStep(); |
4530 | int hStep1 = t.horizontalScrollBar()->singleStep(); |
4531 | QVERIFY(vStep1 > 1); |
4532 | QVERIFY(hStep1 > 1); |
4533 | |
4534 | t.verticalScrollBar()->setSingleStep(1); |
4535 | t.setGeometry(ax: 300, ay: 300, aw: 300, ah: 300); |
4536 | QCOMPARE(t.verticalScrollBar()->singleStep(), 1); |
4537 | |
4538 | t.horizontalScrollBar()->setSingleStep(1); |
4539 | t.setGeometry(ax: 400, ay: 400, aw: 400, ah: 400); |
4540 | QCOMPARE(t.horizontalScrollBar()->singleStep(), 1); |
4541 | |
4542 | t.setGeometry(ax: 200, ay: 200, aw: 200, ah: 200); |
4543 | t.verticalScrollBar()->setSingleStep(-1); |
4544 | t.horizontalScrollBar()->setSingleStep(-1); |
4545 | QCOMPARE(vStep1, t.verticalScrollBar()->singleStep()); |
4546 | QCOMPARE(hStep1, t.horizontalScrollBar()->singleStep()); |
4547 | } |
4548 | |
4549 | void tst_QTableView::taskQTBUG_50171_selectRowAfterSwapColumns() |
4550 | { |
4551 | { |
4552 | QtTestTableView tableView; |
4553 | QtTestTableModel model(2, 3); |
4554 | tableView.setModel(&model); |
4555 | |
4556 | tableView.horizontalHeader()->swapSections(first: 1, second: 2); |
4557 | tableView.horizontalHeader()->hideSection(alogicalIndex: 0); |
4558 | tableView.selectRow(row: 1); |
4559 | |
4560 | QItemSelectionModel* tableSelectionModel = tableView.selectionModel(); |
4561 | QCOMPARE(tableSelectionModel->isRowSelected(1, QModelIndex()), true); |
4562 | QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 0)), false); |
4563 | QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 1)), false); |
4564 | QCOMPARE(tableSelectionModel->isSelected(tableView.model()->index(0, 2)), false); |
4565 | } |
4566 | |
4567 | { |
4568 | QtTestTableView tableView; |
4569 | QtTestTableModel model(3, 2); |
4570 | tableView.setModel(&model); |
4571 | |
4572 | tableView.verticalHeader()->swapSections(first: 1, second: 2); |
4573 | tableView.verticalHeader()->hideSection(alogicalIndex: 0); |
4574 | tableView.selectColumn(column: 1); |
4575 | |
4576 | QItemSelectionModel* sModel = tableView.selectionModel(); |
4577 | QCOMPARE(sModel->isColumnSelected(1, QModelIndex()), true); |
4578 | QCOMPARE(sModel->isSelected(tableView.model()->index(0, 0)), false); |
4579 | QCOMPARE(sModel->isSelected(tableView.model()->index(1, 0)), false); |
4580 | QCOMPARE(sModel->isSelected(tableView.model()->index(2, 0)), false); |
4581 | } |
4582 | } |
4583 | |
4584 | class DeselectTableWidget : public QTableWidget |
4585 | { |
4586 | public: |
4587 | using QTableWidget::QTableWidget; |
4588 | QItemSelectionModel::SelectionFlags selectionCommand(const QModelIndex &, |
4589 | const QEvent * = nullptr) const override |
4590 | { |
4591 | return QItemSelectionModel::Toggle; |
4592 | } |
4593 | }; |
4594 | |
4595 | void tst_QTableView::deselectRow() |
4596 | { |
4597 | DeselectTableWidget tw(20, 20); |
4598 | tw.show(); |
4599 | QVERIFY(QTest::qWaitForWindowExposed(&tw)); |
4600 | tw.hideColumn(column: 0); |
4601 | QVERIFY(tw.isColumnHidden(0)); |
4602 | tw.selectRow(row: 1); |
4603 | QVERIFY(tw.selectionModel()->isRowSelected(1, QModelIndex())); |
4604 | tw.selectRow(row: 1); |
4605 | // QTBUG-79092 - deselection was not possible when column 0 was hidden |
4606 | QVERIFY(!tw.selectionModel()->isRowSelected(1, QModelIndex())); |
4607 | } |
4608 | |
4609 | // This has nothing to do with QTableView, but it's convenient to reuse the QtTestTableModel |
4610 | #if QT_CONFIG(textmarkdownwriter) |
4611 | |
4612 | // #define DEBUG_WRITE_OUTPUT |
4613 | |
4614 | void tst_QTableView::markdownWriter() |
4615 | { |
4616 | QtTestTableModel model(2, 3); |
4617 | QString md; |
4618 | { |
4619 | QTextStream stream(&md); |
4620 | QTextMarkdownWriter writer(stream, QTextDocument::MarkdownDialectGitHub); |
4621 | writer.writeTable(table: &model); |
4622 | } |
4623 | |
4624 | #ifdef DEBUG_WRITE_OUTPUT |
4625 | { |
4626 | QFile out("/tmp/table.md" ); |
4627 | out.open(QFile::WriteOnly); |
4628 | out.write(md.toUtf8()); |
4629 | out.close(); |
4630 | } |
4631 | #endif |
4632 | |
4633 | QCOMPARE(md, QString::fromLatin1("|1 |2 |3 |\n|-------|-------|-------|\n|[0,0,0]|[0,1,0]|[0,2,0]|\n|[1,0,0]|[1,1,0]|[1,2,0]|\n" )); |
4634 | } |
4635 | #endif |
4636 | |
4637 | QTEST_MAIN(tst_QTableView) |
4638 | #include "tst_qtableview.moc" |
4639 | |