1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the Technology Preview License Agreement accompanying
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include <qstandarditemmodel.h>
45 #include <qitemdelegate.h>
46 #include <qcolumnview.h>
47 #include "../../../src/gui/itemviews/qcolumnviewgrip_p.h"
49 #include "../../../src/gui/dialogs/qfilesystemmodel_p.h"
51 #include <qdirmodel.h>
52 #include <qstringlistmodel.h>
54 #include <qitemdelegate.h>
55 #include <qscrollbar.h>
56 #include <private/qcolumnview_p.h>
57 #include "../../shared/util.h"
62 #define ANIMATION_DELAY 300
64 class tst_QColumnView
: public QObject
{
69 virtual ~tst_QColumnView();
80 void scrollContentsBy_data();
81 void scrollContentsBy();
84 void moveCursor_data();
88 void selectedColumns();
90 void setSelectionModel();
91 void visualRegionForSelection();
93 void dynamicModelChanges();
96 void moveGrip_basic();
107 void changeSameColumn();
108 void parentCurrentIndex_data();
109 void parentCurrentIndex();
114 void setPreviewWidget();
117 class TreeModel
: public QStandardItemModel
122 for (int j
= 0; j
< 10; ++j
) {
123 QStandardItem
*parentItem
= invisibleRootItem();
124 for (int i
= 0; i
< 10; ++i
) {
125 QStandardItem
*item
= new QStandardItem(QString("item %0").arg(i
));
126 parentItem
->appendRow(item
);
127 QStandardItem
*item2
= new QStandardItem(QString("item %0").arg(i
));
128 parentItem
->appendRow(item2
);
129 item2
->appendRow(new QStandardItem(QString("item %0").arg(i
)));
130 parentItem
->appendRow(new QStandardItem(QString("file %0").arg(i
)));
136 inline QModelIndex
firstLevel() { return index(0, 0, QModelIndex()); }
137 inline QModelIndex
secondLevel() { return index(0, 0, firstLevel()); }
138 inline QModelIndex
thirdLevel() { return index(0, 0, secondLevel()); }
141 class ColumnView
: public QColumnView
{
144 ColumnView(QWidget
*parent
= 0) : QColumnView(parent
){}
146 QList
<QPointer
<QAbstractItemView
> > createdColumns
;
147 void ScrollContentsBy(int x
, int y
) {scrollContentsBy(x
,y
); }
148 int HorizontalOffset() const { return horizontalOffset(); }
149 void emitClicked() { emit
clicked(QModelIndex()); }
151 enum PublicCursorAction
{
152 MoveUp
= QAbstractItemView::MoveUp
,
153 MoveDown
= QAbstractItemView::MoveDown
,
154 MoveLeft
= QAbstractItemView::MoveLeft
,
155 MoveRight
= QAbstractItemView::MoveRight
,
156 MoveHome
= QAbstractItemView::MoveHome
,
157 MoveEnd
= QAbstractItemView::MoveEnd
,
158 MovePageUp
= QAbstractItemView::MovePageUp
,
159 MovePageDown
= QAbstractItemView::MovePageDown
,
160 MoveNext
= QAbstractItemView::MoveNext
,
161 MovePrevious
= QAbstractItemView::MovePrevious
164 inline QModelIndex
MoveCursor(PublicCursorAction ca
, Qt::KeyboardModifiers kbm
)
165 { return QColumnView::moveCursor((CursorAction
)ca
, kbm
); }
166 bool IsIndexHidden(const QModelIndex
&index
) const
167 { return isIndexHidden(index
); }
169 void setSelection(const QRect
& rect
, QItemSelectionModel::SelectionFlags command
)
171 QColumnView::setSelection(rect
, command
);
174 QRegion
visualRegionForSelection(QItemSelection selection
){
175 return QColumnView::visualRegionForSelection(selection
);
178 QAbstractItemView
*createColumn(const QModelIndex
&index
) {
179 QAbstractItemView
*view
= QColumnView::createColumn(index
);
180 QPointer
<QAbstractItemView
> savedView
= view
;
181 createdColumns
.append(savedView
);
187 tst_QColumnView::tst_QColumnView()
191 tst_QColumnView::~tst_QColumnView()
195 void tst_QColumnView::init()
197 qApp
->setLayoutDirection(Qt::LeftToRight
);
198 #ifdef Q_OS_WINCE //disable magic for WindowsCE
199 qApp
->setAutoMaximizeThreshold(-1);
203 void tst_QColumnView::cleanup()
207 void tst_QColumnView::rootIndex()
211 view
.setRootIndex(QModelIndex());
214 view
.setModel(&model
);
217 QModelIndex drive
= model
.firstLevel();
218 QVERIFY(view
.visualRect(drive
).isValid());
219 view
.setRootIndex(QModelIndex());
220 QCOMPARE(view
.HorizontalOffset(), 0);
221 QCOMPARE(view
.rootIndex(), QModelIndex());
222 QVERIFY(view
.visualRect(drive
).isValid());
224 // A item under the rootIndex exists
225 QModelIndex home
= model
.thirdLevel();
226 QModelIndex homeFile
= model
.index(0, 0, home
);
228 while (i
< model
.rowCount(home
) - 1 && !model
.hasChildren(homeFile
))
229 homeFile
= model
.index(++i
, 0, home
);
230 view
.setRootIndex(home
);
231 QCOMPARE(view
.HorizontalOffset(), 0);
232 QCOMPARE(view
.rootIndex(), home
);
233 QVERIFY(!view
.visualRect(drive
).isValid());
234 QVERIFY(!view
.visualRect(home
).isValid());
235 if (homeFile
.isValid())
236 QVERIFY(view
.visualRect(homeFile
).isValid());
238 // set root when there already is one and everything should still be ok
239 view
.setRootIndex(home
);
240 view
.setCurrentIndex(homeFile
);
241 view
.scrollTo(model
.index(0,0, homeFile
));
242 QCOMPARE(view
.HorizontalOffset(), 0);
243 QCOMPARE(view
.rootIndex(), home
);
244 QVERIFY(!view
.visualRect(drive
).isValid());
245 QVERIFY(!view
.visualRect(home
).isValid());
246 if (homeFile
.isValid())
247 QVERIFY(view
.visualRect(homeFile
).isValid());
250 homeFile
= model
.thirdLevel();
251 home
= homeFile
.parent();
252 view
.setRootIndex(home
);
253 view
.setCurrentIndex(homeFile
);
256 QModelIndex two
= model
.index(0, 0, homeFile
);
257 while (i
< model
.rowCount(homeFile
) - 1 && !model
.hasChildren(two
))
258 two
= model
.index(++i
, 0, homeFile
);
259 qApp
->processEvents();
260 QTest::qWait(ANIMATION_DELAY
);
261 view
.setCurrentIndex(two
);
263 QTest::qWait(ANIMATION_DELAY
);
264 qApp
->processEvents();
265 QVERIFY(two
.isValid());
266 QVERIFY(view
.HorizontalOffset() != 0);
268 view
.setRootIndex(homeFile
);
269 QCOMPARE(view
.HorizontalOffset(), 0);
272 void tst_QColumnView::grips()
276 view
.setModel(&model
);
277 QCOMPARE(view
.resizeGripsVisible(), true);
279 view
.setResizeGripsVisible(true);
280 QCOMPARE(view
.resizeGripsVisible(), true);
283 const QObjectList list
= view
.viewport()->children();
284 for (int i
= 0 ; i
< list
.count(); ++i
) {
285 if (QAbstractItemView
*view
= qobject_cast
<QAbstractItemView
*>(list
.at(i
)))
286 QVERIFY(view
->cornerWidget() != 0);
289 view
.setResizeGripsVisible(false);
290 QCOMPARE(view
.resizeGripsVisible(), false);
293 const QObjectList list
= view
.viewport()->children();
294 for (int i
= 0 ; i
< list
.count(); ++i
) {
295 if (QAbstractItemView
*view
= qobject_cast
<QAbstractItemView
*>(list
.at(i
))) {
296 if (view
->isVisible())
297 QVERIFY(view
->cornerWidget() == 0);
302 view
.setResizeGripsVisible(true);
303 QCOMPARE(view
.resizeGripsVisible(), true);
306 void tst_QColumnView::isIndexHidden()
310 QCOMPARE(view
.IsIndexHidden(idx
), false);
312 view
.setModel(&model
);
313 QCOMPARE(view
.IsIndexHidden(idx
), false);
316 void tst_QColumnView::indexAt()
319 QCOMPARE(view
.indexAt(QPoint(0,0)), QModelIndex());
321 view
.setModel(&model
);
323 QModelIndex home
= model
.index(QDir::homePath());
324 QModelIndex homeFile
= model
.index(0, 0, home
);
325 if (!homeFile
.isValid())
327 view
.setRootIndex(home
);
328 QRect rect
= view
.visualRect(QModelIndex());
329 QVERIFY(!rect
.isValid());
330 rect
= view
.visualRect(homeFile
);
331 QVERIFY(rect
.isValid());
334 for (int i
= 0; i
< model
.rowCount(home
); ++i
) {
335 child
= model
.index(i
, 0, home
);
336 rect
= view
.visualRect(child
);
337 QVERIFY(rect
.isValid());
339 QVERIFY(rect
.top() > 0);
340 QCOMPARE(view
.indexAt(rect
.center()), child
);
342 view
.selectionModel()->select(child
, QItemSelectionModel::SelectCurrent
);
343 view
.setCurrentIndex(child
);
344 qApp
->processEvents();
347 // test that the second row doesn't start at 0
348 if (model
.rowCount(child
) > 0) {
349 child
= model
.index(0, 0, child
);
350 QVERIFY(child
.isValid());
351 rect
= view
.visualRect(child
);
352 QVERIFY(rect
.isValid());
353 QVERIFY(rect
.left() > 0);
354 QCOMPARE(view
.indexAt(rect
.center()), child
);
360 void tst_QColumnView::scrollContentsBy_data()
362 QTest::addColumn
<bool>("reverse");
363 QTest::newRow("normal") << false;
364 QTest::newRow("reverse") << true;
367 void tst_QColumnView::scrollContentsBy()
369 QFETCH(bool, reverse
);
371 qApp
->setLayoutDirection(Qt::RightToLeft
);
373 view
.ScrollContentsBy(-1, -1);
374 view
.ScrollContentsBy(0, 0);
377 view
.setModel(&model
);
378 view
.ScrollContentsBy(0, 0);
380 QModelIndex home
= model
.thirdLevel();
381 view
.setCurrentIndex(home
);
382 QTest::qWait(ANIMATION_DELAY
);
383 view
.ScrollContentsBy(0, 0);
386 void tst_QColumnView::scrollTo_data()
388 QTest::addColumn
<bool>("reverse");
389 QTest::addColumn
<bool>("giveFocus");
390 /// ### add test later for giveFocus == true
391 QTest::newRow("normal") << false << false;
392 QTest::newRow("reverse") << true << false;
395 void tst_QColumnView::scrollTo()
397 QFETCH(bool, reverse
);
398 QFETCH(bool, giveFocus
);
400 qApp
->setLayoutDirection(Qt::RightToLeft
);
402 view
.resize(200, 200);
404 view
.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible
);
405 QCOMPARE(view
.HorizontalOffset(), 0);
408 view
.setModel(&model
);
409 view
.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible
);
412 home
= model
.index(0, 0, home
);
413 home
= model
.index(0, 0, home
);
414 home
= model
.index(0, 0, home
);
415 view
.scrollTo(home
, QAbstractItemView::EnsureVisible
);
416 QModelIndex homeFile
= model
.index(0, 0, home
);
417 view
.setRootIndex(home
);
419 QModelIndex index
= model
.index(0, 0, home
);
420 view
.scrollTo(index
, QAbstractItemView::EnsureVisible
);
421 QCOMPARE(view
.HorizontalOffset(), 0);
423 // Embedded requires that at least one widget have focus
428 view
.setFocus(Qt::OtherFocusReason
);
431 QTRY_COMPARE(view
.hasFocus(), giveFocus
);
432 // scroll to the right
434 int last
= view
.HorizontalOffset();
435 while(model
.hasChildren(index
) && level
< 5) {
436 view
.setCurrentIndex(index
);
437 QTest::qWait(ANIMATION_DELAY
);
438 view
.scrollTo(index
, QAbstractItemView::EnsureVisible
);
439 QTest::qWait(ANIMATION_DELAY
);
440 qApp
->processEvents();
441 index
= model
.index(0, 0, index
);
445 QTRY_VERIFY(view
.HorizontalOffset() < 0);
446 QTRY_VERIFY(last
> view
.HorizontalOffset());
448 QTRY_VERIFY(view
.HorizontalOffset() > 0);
449 QTRY_VERIFY(last
< view
.HorizontalOffset());
452 last
= view
.HorizontalOffset();
455 // scroll to the left
457 while(index
.parent().isValid() && index
!= view
.rootIndex()) {
458 view
.setCurrentIndex(index
);
459 QTest::qWait(ANIMATION_DELAY
);
460 view
.scrollTo(index
, QAbstractItemView::EnsureVisible
);
461 index
= index
.parent();
462 if (start
!= level
) {
464 QTRY_VERIFY(last
< view
.HorizontalOffset());
466 QTRY_VERIFY(last
> view
.HorizontalOffset());
469 last
= view
.HorizontalOffset();
471 // It shouldn't automatically steal focus if it doesn't have it
472 QTRY_COMPARE(view
.hasFocus(), giveFocus
);
474 // Try scrolling to something that is above the root index
475 home
= model
.index(0, 0, QModelIndex());
476 QModelIndex temp
= model
.index(1, 0, home
);
477 home
= model
.index(0, 0, home
);
478 home
= model
.index(0, 0, home
);
479 view
.setRootIndex(home
);
480 view
.scrollTo(model
.index(0, 0, home
));
481 QTest::qWait(ANIMATION_DELAY
);
485 void tst_QColumnView::moveCursor_data()
487 QTest::addColumn
<bool>("reverse");
488 QTest::newRow("normal") << false;
489 QTest::newRow("reverse") << true;
492 void tst_QColumnView::moveCursor()
494 QFETCH(bool, reverse
);
496 qApp
->setLayoutDirection(Qt::RightToLeft
);
500 view
.MoveCursor(ColumnView::MoveUp
, Qt::NoModifier
);
503 QCOMPARE(view
.MoveCursor(ColumnView::MoveEnd
, Qt::NoModifier
), QModelIndex());
506 view
.setModel(&model
);
507 QModelIndex home
= model
.index(QDir::homePath());
508 QModelIndex ci
= view
.currentIndex();
509 QCOMPARE(view
.MoveCursor(ColumnView::MoveUp
, Qt::NoModifier
), QModelIndex());
510 QCOMPARE(view
.MoveCursor(ColumnView::MoveDown
, Qt::NoModifier
), QModelIndex());
513 view
.setCurrentIndex(model
.index(0,0));
514 ColumnView::PublicCursorAction action
= reverse
? ColumnView::MoveRight
: ColumnView::MoveLeft
;
515 QCOMPARE(view
.MoveCursor(action
, Qt::NoModifier
), model
.index(0,0));
517 // left shouldn't move up
519 ci
= model
.index(0, 0);
520 while (i
< model
.rowCount() - 1 && !model
.hasChildren(ci
))
521 ci
= model
.index(++i
, 0);
522 QVERIFY(model
.hasChildren(ci
));
523 view
.setCurrentIndex(ci
);
524 action
= reverse
? ColumnView::MoveRight
: ColumnView::MoveLeft
;
525 QCOMPARE(view
.MoveCursor(action
, Qt::NoModifier
), ci
);
527 // now move to the left (i.e. move over one column)
528 view
.setCurrentIndex(home
);
529 QCOMPARE(view
.MoveCursor(action
, Qt::NoModifier
), home
.parent());
532 action
= reverse
? ColumnView::MoveLeft
: ColumnView::MoveRight
;
533 view
.setCurrentIndex(ci
);
534 QModelIndex mc
= view
.MoveCursor(action
, Qt::NoModifier
);
535 QCOMPARE(mc
, model
.index(0,0, ci
));
537 // next one should move down
538 QModelIndex idx
= model
.index(0, 0, ci
);
539 while (model
.hasChildren(idx
) && model
.rowCount(ci
) > idx
.row() + 1)
540 idx
= idx
.sibling(idx
.row() + 1, idx
.column());
541 view
.setCurrentIndex(idx
);
542 mc
= view
.MoveCursor(action
, Qt::NoModifier
);
543 QCOMPARE(mc
, idx
.sibling(idx
.row() + 1, idx
.column()));
546 void tst_QColumnView::selectAll()
552 view
.setModel(&model
);
554 QVERIFY(view
.selectionModel()->selectedIndexes().count() >= 0);
556 QModelIndex home
= model
.index(QDir::homePath());
557 view
.setCurrentIndex(home
);
559 QVERIFY(view
.selectionModel()->selectedIndexes().count() > 0);
562 for (int i
= 0; i
< model
.rowCount(home
); ++i
)
563 if (!model
.hasChildren(model
.index(i
, 0, home
))) {
564 file
= model
.index(i
, 0, home
);
567 view
.setCurrentIndex(file
);
569 QVERIFY(view
.selectionModel()->selectedIndexes().count() > 0);
571 view
.setCurrentIndex(QModelIndex());
572 QVERIFY(view
.selectionModel()->selectedIndexes().count() == 0);
575 void tst_QColumnView::clicked()
580 view
.setModel(&model
);
581 view
.resize(800,300);
584 QModelIndex home
= model
.index(QDir::homePath());
585 QVERIFY(home
.isValid());
586 view
.setCurrentIndex(home
);
587 QTest::qWait(ANIMATION_DELAY
);
589 QModelIndex parent
= home
.parent();
590 QVERIFY(parent
.isValid());
592 qRegisterMetaType
<QModelIndex
>("QModelIndex");
593 QSignalSpy
clickedSpy(&view
, SIGNAL(clicked(const QModelIndex
&)));
595 QPoint localPoint
= view
.visualRect(home
).center();
596 QTest::mouseClick(view
.viewport(), Qt::LeftButton
, 0, localPoint
);
597 QCOMPARE(clickedSpy
.count(), 1);
598 qApp
->processEvents();
600 if (sizeof(qreal
) != sizeof(double)) {
601 QSKIP("Skipped due to rounding errors", SkipAll
);
604 for (int i
= 0; i
< view
.createdColumns
.count(); ++i
) {
605 QAbstractItemView
*column
= view
.createdColumns
.at(i
);
606 if (column
&& column
->selectionModel() && (column
->rootIndex() == home
))
607 QVERIFY(column
->selectionModel()->selectedIndexes().isEmpty());
611 void tst_QColumnView::selectedColumns()
615 view
.setModel(&model
);
616 view
.resize(800,300);
619 QModelIndex home
= model
.index(QDir::homePath());
620 view
.setCurrentIndex(home
);
622 QTest::qWait(ANIMATION_DELAY
);
624 for (int i
= 0; i
< view
.createdColumns
.count(); ++i
) {
625 QAbstractItemView
*column
= view
.createdColumns
.at(i
);
628 if (!column
->rootIndex().isValid() || column
->rootIndex() == home
)
630 QTRY_VERIFY(column
->currentIndex().isValid());
634 void tst_QColumnView::setSelection()
637 // shouldn't do anything, it falls to the columns to handle this
639 view
.setSelection(r
, QItemSelectionModel::NoUpdate
);
642 void tst_QColumnView::setSelectionModel()
646 view
.setModel(&model
);
649 QModelIndex home
= model
.index(QDir::homePath());
650 view
.setCurrentIndex(home
);
651 QTest::qWait(ANIMATION_DELAY
);
653 QItemSelectionModel
*selectionModel
= new QItemSelectionModel(&model
);
654 view
.setSelectionModel(selectionModel
);
657 for (int i
= 0; i
< view
.createdColumns
.count(); ++i
) {
658 if (view
.createdColumns
.at(i
)->selectionModel() == selectionModel
) {
666 void tst_QColumnView::visualRegionForSelection()
669 QItemSelection emptyItemSelection
;
670 QCOMPARE(QRegion(), view
.visualRegionForSelection(emptyItemSelection
));
672 // a region that isn't empty
674 view
.setModel(&model
);
676 // On Windows CE the home directory might actually be empty.
678 QString location
= QDir::homePath();
680 QString location
= QLatin1String("/Windows");
683 QModelIndex home
= model
.index(location
);
684 QVERIFY(model
.rowCount(home
) > 1);
685 QItemSelection
itemSelection(model
.index(0, 0, home
), model
.index(model
.rowCount(home
) - 1, 0, home
));
686 QVERIFY(QRegion() != view
.visualRegionForSelection(itemSelection
));
689 void tst_QColumnView::moveGrip_basic()
692 QColumnViewGrip
*grip
= new QColumnViewGrip(&view
);
693 QSignalSpy
spy(grip
, SIGNAL(gripMoved(int)));
694 view
.setCornerWidget(grip
);
695 int oldX
= view
.width();
697 QCOMPARE(oldX
+ 10, view
.width());
699 QCOMPARE(oldX
, view
.width());
700 grip
->moveGrip(-800);
701 QVERIFY(view
.width() == 0 || view
.width() == 1);
703 view
.setMinimumWidth(200);
704 grip
->moveGrip(-800);
705 QCOMPARE(view
.width(), 200);
706 QCOMPARE(spy
.count(), 5);
709 void tst_QColumnView::moveGrip_data()
711 QTest::addColumn
<bool>("reverse");
712 QTest::newRow("normal") << false;
713 QTest::newRow("reverse") << true;
716 void tst_QColumnView::moveGrip()
718 QFETCH(bool, reverse
);
720 qApp
->setLayoutDirection(Qt::RightToLeft
);
723 view
.setModel(&model
);
724 QModelIndex home
= model
.thirdLevel();
725 view
.setCurrentIndex(home
);
726 view
.resize(640, 200);
728 QTest::qWait(ANIMATION_DELAY
);
730 int columnNum
= view
.createdColumns
.count() - 2;
731 QVERIFY(columnNum
>= 0);
732 QObjectList list
= view
.createdColumns
[columnNum
]->children();
733 QColumnViewGrip
*grip
= 0;
734 for (int i
= 0; i
< list
.count(); ++i
) {
735 if ((grip
= qobject_cast
<QColumnViewGrip
*>(list
[i
]))) {
742 QAbstractItemView
*column
= qobject_cast
<QAbstractItemView
*>(grip
->parent());
743 int oldX
= column
->width();
744 QCOMPARE(view
.columnWidths()[columnNum
], oldX
);
746 QCOMPARE(view
.columnWidths()[columnNum
], (oldX
+ (reverse
? -10 : 10)));
749 void tst_QColumnView::doubleClick()
752 QColumnViewGrip
*grip
= new QColumnViewGrip(&view
);
753 QSignalSpy
spy(grip
, SIGNAL(gripMoved(int)));
754 view
.setCornerWidget(grip
);
755 view
.resize(200, 200);
756 QCOMPARE(view
.width(), 200);
757 QTest::mouseDClick(grip
, Qt::LeftButton
);
758 QCOMPARE(view
.width(), view
.sizeHint().width());
759 QCOMPARE(spy
.count(), 1);
762 void tst_QColumnView::gripMoved()
765 QColumnViewGrip
*grip
= new QColumnViewGrip(&view
);
766 QSignalSpy
spy(grip
, SIGNAL(gripMoved(int)));
767 view
.setCornerWidget(grip
);
769 view
.resize(200, 200);
770 qApp
->processEvents();
772 int oldWidth
= view
.width();
774 QTest::mousePress(grip
, Qt::LeftButton
, 0, QPoint(1,1));
775 //QTest::mouseMove(grip, QPoint(grip->globalX()+50, y));
777 QPoint posNew
= QPoint(grip
->mapToGlobal(QPoint(1,1)).x() + 65, 0);
778 QMouseEvent
*event
= new QMouseEvent(QEvent::MouseMove
, posNew
, posNew
, Qt::LeftButton
, Qt::LeftButton
,Qt::NoModifier
);
779 QCoreApplication::postEvent(grip
, event
);
780 QCoreApplication::processEvents();
781 QTest::mouseRelease(grip
, Qt::LeftButton
);
783 QCOMPARE(spy
.count(), 1);
784 QCOMPARE(view
.width(), oldWidth
+ 65);
787 void tst_QColumnView::preview()
790 QCOMPARE(view
.previewWidget(), (QWidget
*)0);
792 view
.setModel(&model
);
793 QCOMPARE(view
.previewWidget(), (QWidget
*)0);
794 QModelIndex home
= model
.index(0, 0);
795 QVERIFY(home
.isValid());
796 QVERIFY(model
.hasChildren(home
));
797 view
.setCurrentIndex(home
);
798 QCOMPARE(view
.previewWidget(), (QWidget
*)0);
801 QVERIFY(model
.rowCount(home
) > 0);
802 for (int i
= 0; i
< model
.rowCount(home
); ++i
) {
803 if (!model
.hasChildren(model
.index(i
, 0, home
))) {
804 file
= model
.index(i
, 0, home
);
808 QVERIFY(file
.isValid());
809 view
.setCurrentIndex(file
);
810 QVERIFY(view
.previewWidget() != (QWidget
*)0);
812 QWidget
*previewWidget
= new QWidget(&view
);
813 view
.setPreviewWidget(previewWidget
);
814 QCOMPARE(view
.previewWidget(), previewWidget
);
815 QVERIFY(previewWidget
->parent() != ((QWidget
*)&view
));
816 view
.setCurrentIndex(home
);
818 // previewWidget should be marked for deletion
819 QWidget
*previewWidget2
= new QWidget(&view
);
820 view
.setPreviewWidget(previewWidget2
);
821 QCOMPARE(view
.previewWidget(), previewWidget2
);
824 void tst_QColumnView::swapPreview()
826 // swap the preview widget in updatePreviewWidget
829 sl
<< QLatin1String("test");
830 QStringListModel
model(sl
);
831 view
.setModel(&model
);
832 view
.setCurrentIndex(view
.indexAt(QPoint(1, 1)));
833 connect(&view
, SIGNAL(updatePreviewWidget(const QModelIndex
&)),
834 this, SLOT(setPreviewWidget()));
835 view
.setCurrentIndex(view
.indexAt(QPoint(1, 1)));
836 QTest::qWait(ANIMATION_DELAY
);
837 qApp
->processEvents();
840 void tst_QColumnView::setPreviewWidget()
842 ((QColumnView
*)sender())->setPreviewWidget(new QWidget
);
845 void tst_QColumnView::sizes()
848 QCOMPARE(view
.columnWidths().count(), 0);
851 newSizes
<< 10 << 4 << 50 << 6;
853 QList
<int> visibleSizes
;
854 view
.setColumnWidths(newSizes
);
855 QCOMPARE(view
.columnWidths(), visibleSizes
);
858 view
.setModel(&model
);
859 QModelIndex home
= model
.index(QDir::homePath());
860 view
.setCurrentIndex(home
);
862 QList
<int> postSizes
= view
.columnWidths().mid(0, newSizes
.count());
863 QCOMPARE(postSizes
, newSizes
.mid(0, postSizes
.count()));
865 QVERIFY(view
.columnWidths().count() > 1);
866 QList
<int> smallerSizes
;
868 view
.setColumnWidths(smallerSizes
);
869 QList
<int> expectedSizes
= newSizes
;
870 expectedSizes
[0] = 6;
871 postSizes
= view
.columnWidths().mid(0, newSizes
.count());
872 QCOMPARE(postSizes
, expectedSizes
.mid(0, postSizes
.count()));
875 void tst_QColumnView::rowDelegate()
878 QItemDelegate
*d
= new QItemDelegate
;
879 view
.setItemDelegateForRow(3, d
);
882 view
.setModel(&model
);
883 for (int i
= 0; i
< view
.createdColumns
.count(); ++i
) {
884 QAbstractItemView
*column
= view
.createdColumns
.at(i
);
885 QCOMPARE(column
->itemDelegateForRow(3), (QAbstractItemDelegate
*)d
);
890 void tst_QColumnView::resize()
894 view
.setModel(&model
);
895 view
.resize(200, 200);
898 QModelIndex home
= model
.index(QDir::homePath()).parent();
899 view
.setCurrentIndex(home
);
900 QTest::qWait(ANIMATION_DELAY
);
901 view
.resize(200, 300);
902 QTest::qWait(ANIMATION_DELAY
);
904 QVERIFY(view
.horizontalScrollBar()->maximum() != 0);
905 view
.resize(view
.horizontalScrollBar()->maximum() * 10, 300);
906 QTest::qWait(ANIMATION_DELAY
);
907 QVERIFY(view
.horizontalScrollBar()->maximum() <= 0);
910 void tst_QColumnView::changeSameColumn()
914 view
.setModel(&model
);
917 QModelIndex home
= model
.secondLevel();
918 //index(QDir::homePath());
919 view
.setCurrentIndex(home
);
920 for (int i
= 0; i
< model
.rowCount(home
.parent()); ++i
) {
921 QModelIndex idx
= model
.index(i
, 0, home
.parent());
922 if (model
.hasChildren(idx
) && idx
!= home
) {
927 QVERIFY(second
.isValid());
929 QList
<QPointer
<QAbstractItemView
> > old
= view
.createdColumns
;
930 view
.setCurrentIndex(second
);
932 QCOMPARE(old
, view
.createdColumns
);
935 void tst_QColumnView::parentCurrentIndex_data()
937 QTest::addColumn
<int>("firstRow");
938 QTest::addColumn
<int>("secondRow");
939 QTest::newRow("down") << 0 << 1;
940 QTest::newRow("up") << 1 << 0;
943 void tst_QColumnView::parentCurrentIndex()
945 QFETCH(int, firstRow
);
946 QFETCH(int, secondRow
);
950 view
.setModel(&model
);
956 first
= model
.index(0, 0, QModelIndex());
957 second
= model
.index(firstRow
, 0, first
);
958 third
= model
.index(0, 0, second
);
959 QVERIFY(first
.isValid());
960 QVERIFY(second
.isValid());
961 QVERIFY(third
.isValid());
962 view
.setCurrentIndex(third
);
963 QTest::qWait(ANIMATION_DELAY
);
964 QCOMPARE(view
.createdColumns
[0]->currentIndex(), first
);
965 QCOMPARE(view
.createdColumns
[1]->currentIndex(), second
);
966 QCOMPARE(view
.createdColumns
[2]->currentIndex(), third
);
968 first
= model
.index(0, 0, QModelIndex());
969 second
= model
.index(secondRow
, 0, first
);
970 third
= model
.index(0, 0, second
);
971 QVERIFY(first
.isValid());
972 QVERIFY(second
.isValid());
973 QVERIFY(third
.isValid());
974 view
.setCurrentIndex(third
);
975 QTest::qWait(ANIMATION_DELAY
);
976 QTRY_COMPARE(view
.createdColumns
[0]->currentIndex(), first
);
977 QTRY_COMPARE(view
.createdColumns
[1]->currentIndex(), second
);
978 QTRY_COMPARE(view
.createdColumns
[2]->currentIndex(), third
);
981 void tst_QColumnView::pullRug_data()
983 QTest::addColumn
<bool>("removeModel");
984 QTest::newRow("model") << true;
985 QTest::newRow("index") << false;
988 void tst_QColumnView::pullRug()
990 QFETCH(bool, removeModel
);
993 view
.setModel(&model
);
994 QModelIndex home
= model
.thirdLevel();
995 view
.setCurrentIndex(home
);
999 view
.setCurrentIndex(QModelIndex());
1000 QTest::qWait(ANIMATION_DELAY
);
1004 void tst_QColumnView::dynamicModelChanges()
1006 struct MyItemDelegate
: public QItemDelegate
1008 void paint(QPainter
*painter
,
1009 const QStyleOptionViewItem
&option
,
1010 const QModelIndex
&index
) const
1012 paintedIndexes
+= index
;
1013 QItemDelegate::paint(painter
, option
, index
);
1016 mutable QSet
<QModelIndex
> paintedIndexes
;
1019 QStandardItemModel model
;
1021 view
.setModel(&model
);
1022 view
.setItemDelegate(&delegate
);
1025 QStandardItem
*item
= new QStandardItem(QLatin1String("item"));
1026 model
.appendRow(item
);
1028 QTest::qWait(200); //let the time for painting to occur
1029 QCOMPARE(delegate
.paintedIndexes
.count(), 1);
1030 QCOMPARE(*delegate
.paintedIndexes
.begin(), model
.index(0,0));
1036 QTEST_MAIN(tst_QColumnView
)
1037 #include "tst_qcolumnview.moc"