diff options
Diffstat (limited to 'tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp')
-rw-r--r-- | tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp | 1040 |
1 files changed, 1040 insertions, 0 deletions
diff --git a/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp new file mode 100644 index 0000000000..364f917511 --- /dev/null +++ b/tests/auto/widgets/itemviews/qcolumnview/tst_qcolumnview.cpp @@ -0,0 +1,1040 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include <qstandarditemmodel.h> +#include <qitemdelegate.h> +#include <qcolumnview.h> +#include "../../../src/widgets/itemviews/qcolumnviewgrip_p.h" +#include "../../../src/widgets/dialogs/qfilesystemmodel_p.h" +#include <qdirmodel.h> +#include <qstringlistmodel.h> +#include <qdebug.h> +#include <qitemdelegate.h> +#include <qscrollbar.h> +#include <private/qcolumnview_p.h> + +//TESTED_CLASS= +//TESTED_FILES= + +#define ANIMATION_DELAY 300 + +class tst_QColumnView : public QObject { + Q_OBJECT + +public: + tst_QColumnView(); + virtual ~tst_QColumnView(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private slots: + void rootIndex(); + void grips(); + void isIndexHidden(); + void indexAt(); + void scrollContentsBy_data(); + void scrollContentsBy(); + void scrollTo_data(); + void scrollTo(); + void moveCursor_data(); + void moveCursor(); + void selectAll(); + void clicked(); + void selectedColumns(); + void setSelection(); + void setSelectionModel(); + void visualRegionForSelection(); + + void dynamicModelChanges(); + + // grip + void moveGrip_basic(); + void moveGrip_data(); + void moveGrip(); + void doubleClick(); + void gripMoved(); + + void preview(); + void swapPreview(); + void sizes(); + void rowDelegate(); + void resize(); + void changeSameColumn(); + void parentCurrentIndex_data(); + void parentCurrentIndex(); + void pullRug_data(); + void pullRug(); + +protected slots: + void setPreviewWidget(); +}; + +class TreeModel : public QStandardItemModel +{ +public: + TreeModel() + { + for (int j = 0; j < 10; ++j) { + QStandardItem *parentItem = invisibleRootItem(); + for (int i = 0; i < 10; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + QStandardItem *item2 = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item2); + item2->appendRow(new QStandardItem(QString("item %0").arg(i))); + parentItem->appendRow(new QStandardItem(QString("file %0").arg(i))); + parentItem = item; + } + } + } + + inline QModelIndex firstLevel() { return index(0, 0, QModelIndex()); } + inline QModelIndex secondLevel() { return index(0, 0, firstLevel()); } + inline QModelIndex thirdLevel() { return index(0, 0, secondLevel()); } +}; + +class ColumnView : public QColumnView { + +public: + ColumnView(QWidget *parent = 0) : QColumnView(parent){} + + QList<QPointer<QAbstractItemView> > createdColumns; + void ScrollContentsBy(int x, int y) {scrollContentsBy(x,y); } + int HorizontalOffset() const { return horizontalOffset(); } + void emitClicked() { emit clicked(QModelIndex()); } + + enum PublicCursorAction { + MoveUp = QAbstractItemView::MoveUp, + MoveDown = QAbstractItemView::MoveDown, + MoveLeft = QAbstractItemView::MoveLeft, + MoveRight = QAbstractItemView::MoveRight, + MoveHome = QAbstractItemView::MoveHome, + MoveEnd = QAbstractItemView::MoveEnd, + MovePageUp = QAbstractItemView::MovePageUp, + MovePageDown = QAbstractItemView::MovePageDown, + MoveNext = QAbstractItemView::MoveNext, + MovePrevious = QAbstractItemView::MovePrevious + }; + + inline QModelIndex MoveCursor(PublicCursorAction ca, Qt::KeyboardModifiers kbm) + { return QColumnView::moveCursor((CursorAction)ca, kbm); } + bool IsIndexHidden(const QModelIndex&index) const + { return isIndexHidden(index); } + + void setSelection(const QRect & rect, QItemSelectionModel::SelectionFlags command ) + { + QColumnView::setSelection(rect, command); + } + + QRegion visualRegionForSelection(QItemSelection selection){ + return QColumnView::visualRegionForSelection(selection); + } +protected: + QAbstractItemView *createColumn(const QModelIndex &index) { + QAbstractItemView *view = QColumnView::createColumn(index); + QPointer<QAbstractItemView> savedView = view; + createdColumns.append(savedView); + return view; + } + +}; + +tst_QColumnView::tst_QColumnView() +{ +} + +tst_QColumnView::~tst_QColumnView() +{ +} + +void tst_QColumnView::init() +{ + qApp->setLayoutDirection(Qt::LeftToRight); +#ifdef Q_OS_WINCE //disable magic for WindowsCE + qApp->setAutoMaximizeThreshold(-1); +#endif +} + +void tst_QColumnView::cleanup() +{ +} + +void tst_QColumnView::rootIndex() +{ + ColumnView view; + // no model + view.setRootIndex(QModelIndex()); + + TreeModel model; + view.setModel(&model); + + // A top level index + QModelIndex drive = model.firstLevel(); + QVERIFY(view.visualRect(drive).isValid()); + view.setRootIndex(QModelIndex()); + QCOMPARE(view.HorizontalOffset(), 0); + QCOMPARE(view.rootIndex(), QModelIndex()); + QVERIFY(view.visualRect(drive).isValid()); + + // A item under the rootIndex exists + QModelIndex home = model.thirdLevel(); + QModelIndex homeFile = model.index(0, 0, home); + int i = 0; + while (i < model.rowCount(home) - 1 && !model.hasChildren(homeFile)) + homeFile = model.index(++i, 0, home); + view.setRootIndex(home); + QCOMPARE(view.HorizontalOffset(), 0); + QCOMPARE(view.rootIndex(), home); + QVERIFY(!view.visualRect(drive).isValid()); + QVERIFY(!view.visualRect(home).isValid()); + if (homeFile.isValid()) + QVERIFY(view.visualRect(homeFile).isValid()); + + // set root when there already is one and everything should still be ok + view.setRootIndex(home); + view.setCurrentIndex(homeFile); + view.scrollTo(model.index(0,0, homeFile)); + QCOMPARE(view.HorizontalOffset(), 0); + QCOMPARE(view.rootIndex(), home); + QVERIFY(!view.visualRect(drive).isValid()); + QVERIFY(!view.visualRect(home).isValid()); + if (homeFile.isValid()) + QVERIFY(view.visualRect(homeFile).isValid()); + + // + homeFile = model.thirdLevel(); + home = homeFile.parent(); + view.setRootIndex(home); + view.setCurrentIndex(homeFile); + view.show(); + i = 0; + QModelIndex two = model.index(0, 0, homeFile); + while (i < model.rowCount(homeFile) - 1 && !model.hasChildren(two)) + two = model.index(++i, 0, homeFile); + qApp->processEvents(); + QTest::qWait(ANIMATION_DELAY); + view.setCurrentIndex(two); + view.scrollTo(two); + QTest::qWait(ANIMATION_DELAY); + qApp->processEvents(); + QVERIFY(two.isValid()); + QVERIFY(view.HorizontalOffset() != 0); + + view.setRootIndex(homeFile); + QCOMPARE(view.HorizontalOffset(), 0); +} + +void tst_QColumnView::grips() +{ + QColumnView view; + QDirModel model; + view.setModel(&model); + QCOMPARE(view.resizeGripsVisible(), true); + + view.setResizeGripsVisible(true); + QCOMPARE(view.resizeGripsVisible(), true); + + { + const QObjectList list = view.viewport()->children(); + for (int i = 0 ; i < list.count(); ++i) { + if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(list.at(i))) + QVERIFY(view->cornerWidget() != 0); + } + } + view.setResizeGripsVisible(false); + QCOMPARE(view.resizeGripsVisible(), false); + + { + const QObjectList list = view.viewport()->children(); + for (int i = 0 ; i < list.count(); ++i) { + if (QAbstractItemView *view = qobject_cast<QAbstractItemView*>(list.at(i))) { + if (view->isVisible()) + QVERIFY(view->cornerWidget() == 0); + } + } + } + + view.setResizeGripsVisible(true); + QCOMPARE(view.resizeGripsVisible(), true); +} + +void tst_QColumnView::isIndexHidden() +{ + ColumnView view; + QModelIndex idx; + QCOMPARE(view.IsIndexHidden(idx), false); + QDirModel model; + view.setModel(&model); + QCOMPARE(view.IsIndexHidden(idx), false); +} + +void tst_QColumnView::indexAt() +{ + QColumnView view; + QCOMPARE(view.indexAt(QPoint(0,0)), QModelIndex()); + QDirModel model; + view.setModel(&model); + + QModelIndex home = model.index(QDir::homePath()); + QModelIndex homeFile = model.index(0, 0, home); + if (!homeFile.isValid()) + return; + view.setRootIndex(home); + QRect rect = view.visualRect(QModelIndex()); + QVERIFY(!rect.isValid()); + rect = view.visualRect(homeFile); + QVERIFY(rect.isValid()); + + QModelIndex child; + for (int i = 0; i < model.rowCount(home); ++i) { + child = model.index(i, 0, home); + rect = view.visualRect(child); + QVERIFY(rect.isValid()); + if (i > 0) + QVERIFY(rect.top() > 0); + QCOMPARE(view.indexAt(rect.center()), child); + + view.selectionModel()->select(child, QItemSelectionModel::SelectCurrent); + view.setCurrentIndex(child); + qApp->processEvents(); + QTest::qWait(200); + + // test that the second row doesn't start at 0 + if (model.rowCount(child) > 0) { + child = model.index(0, 0, child); + QVERIFY(child.isValid()); + rect = view.visualRect(child); + QVERIFY(rect.isValid()); + QVERIFY(rect.left() > 0); + QCOMPARE(view.indexAt(rect.center()), child); + break; + } + } +} + +void tst_QColumnView::scrollContentsBy_data() +{ + QTest::addColumn<bool>("reverse"); + QTest::newRow("normal") << false; + QTest::newRow("reverse") << true; +} + +void tst_QColumnView::scrollContentsBy() +{ + QFETCH(bool, reverse); + if (reverse) + qApp->setLayoutDirection(Qt::RightToLeft); + ColumnView view; + view.ScrollContentsBy(-1, -1); + view.ScrollContentsBy(0, 0); + + TreeModel model; + view.setModel(&model); + view.ScrollContentsBy(0, 0); + + QModelIndex home = model.thirdLevel(); + view.setCurrentIndex(home); + QTest::qWait(ANIMATION_DELAY); + view.ScrollContentsBy(0, 0); +} + +void tst_QColumnView::scrollTo_data() +{ + QTest::addColumn<bool>("reverse"); + QTest::addColumn<bool>("giveFocus"); + /// ### add test later for giveFocus == true + QTest::newRow("normal") << false << false; + QTest::newRow("reverse") << true << false; +} + +void tst_QColumnView::scrollTo() +{ + QFETCH(bool, reverse); + QFETCH(bool, giveFocus); + if (reverse) + qApp->setLayoutDirection(Qt::RightToLeft); + QWidget topLevel; + ColumnView view(&topLevel); + view.resize(200, 200); + topLevel.show(); + view.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible); + QCOMPARE(view.HorizontalOffset(), 0); + + TreeModel model; + view.setModel(&model); + view.scrollTo(QModelIndex(), QAbstractItemView::EnsureVisible); + + QModelIndex home; + home = model.index(0, 0, home); + home = model.index(0, 0, home); + home = model.index(0, 0, home); + view.scrollTo(home, QAbstractItemView::EnsureVisible); + QModelIndex homeFile = model.index(0, 0, home); + view.setRootIndex(home); + + QModelIndex index = model.index(0, 0, home); + view.scrollTo(index, QAbstractItemView::EnsureVisible); + QCOMPARE(view.HorizontalOffset(), 0); + + // Embedded requires that at least one widget have focus + QWidget w; + w.show(); + + if (giveFocus) + view.setFocus(Qt::OtherFocusReason); + else + view.clearFocus(); + + qApp->processEvents(); + QTRY_COMPARE(view.hasFocus(), giveFocus); + // scroll to the right + int level = 0; + int last = view.HorizontalOffset(); + while(model.hasChildren(index) && level < 5) { + view.setCurrentIndex(index); + QTest::qWait(ANIMATION_DELAY); + view.scrollTo(index, QAbstractItemView::EnsureVisible); + QTest::qWait(ANIMATION_DELAY); + qApp->processEvents(); + index = model.index(0, 0, index); + level++; + if (level >= 2) { + if (!reverse) { + QTRY_VERIFY(view.HorizontalOffset() < 0); + QTRY_VERIFY(last > view.HorizontalOffset()); + } else { + QTRY_VERIFY(view.HorizontalOffset() > 0); + QTRY_VERIFY(last < view.HorizontalOffset()); + } + } + last = view.HorizontalOffset(); + } + + // scroll to the left + int start = level; + while(index.parent().isValid() && index != view.rootIndex()) { + view.setCurrentIndex(index); + QTest::qWait(ANIMATION_DELAY); + view.scrollTo(index, QAbstractItemView::EnsureVisible); + index = index.parent(); + if (start != level) { + if (!reverse) + QTRY_VERIFY(last < view.HorizontalOffset()); + else + QTRY_VERIFY(last > view.HorizontalOffset()); + } + level--; + last = view.HorizontalOffset(); + } + // It shouldn't automatically steal focus if it doesn't have it + QTRY_COMPARE(view.hasFocus(), giveFocus); + + // Try scrolling to something that is above the root index + home = model.index(0, 0, QModelIndex()); + QModelIndex temp = model.index(1, 0, home); + home = model.index(0, 0, home); + home = model.index(0, 0, home); + view.setRootIndex(home); + view.scrollTo(model.index(0, 0, home)); + QTest::qWait(ANIMATION_DELAY); + view.scrollTo(temp); +} + +void tst_QColumnView::moveCursor_data() +{ + QTest::addColumn<bool>("reverse"); + QTest::newRow("normal") << false; + QTest::newRow("reverse") << true; +} + +void tst_QColumnView::moveCursor() +{ + QFETCH(bool, reverse); + if (reverse) + qApp->setLayoutDirection(Qt::RightToLeft); + ColumnView view; + + // don't crash + view.MoveCursor(ColumnView::MoveUp, Qt::NoModifier); + + // don't do anything + QCOMPARE(view.MoveCursor(ColumnView::MoveEnd, Qt::NoModifier), QModelIndex()); + + QDirModel model; + view.setModel(&model); + QModelIndex home = model.index(QDir::homePath()); + QModelIndex ci = view.currentIndex(); + QCOMPARE(view.MoveCursor(ColumnView::MoveUp, Qt::NoModifier), QModelIndex()); + QCOMPARE(view.MoveCursor(ColumnView::MoveDown, Qt::NoModifier), QModelIndex()); + + // left at root + view.setCurrentIndex(model.index(0,0)); + ColumnView::PublicCursorAction action = reverse ? ColumnView::MoveRight : ColumnView::MoveLeft; + QCOMPARE(view.MoveCursor(action, Qt::NoModifier), model.index(0,0)); + + // left shouldn't move up + int i = 0; + ci = model.index(0, 0); + while (i < model.rowCount() - 1 && !model.hasChildren(ci)) + ci = model.index(++i, 0); + QVERIFY(model.hasChildren(ci)); + view.setCurrentIndex(ci); + action = reverse ? ColumnView::MoveRight : ColumnView::MoveLeft; + QCOMPARE(view.MoveCursor(action, Qt::NoModifier), ci); + + // now move to the left (i.e. move over one column) + view.setCurrentIndex(home); + QCOMPARE(view.MoveCursor(action, Qt::NoModifier), home.parent()); + + // right + action = reverse ? ColumnView::MoveLeft : ColumnView::MoveRight; + view.setCurrentIndex(ci); + QModelIndex mc = view.MoveCursor(action, Qt::NoModifier); + QCOMPARE(mc, model.index(0,0, ci)); + + // next one should move down + QModelIndex idx = model.index(0, 0, ci); + while (model.hasChildren(idx) && model.rowCount(ci) > idx.row() + 1) + idx = idx.sibling(idx.row() + 1, idx.column()); + view.setCurrentIndex(idx); + mc = view.MoveCursor(action, Qt::NoModifier); + QCOMPARE(mc, idx.sibling(idx.row() + 1, idx.column())); +} + +void tst_QColumnView::selectAll() +{ + ColumnView view; + view.selectAll(); + + QDirModel model; + view.setModel(&model); + view.selectAll(); + QVERIFY(view.selectionModel()->selectedIndexes().count() >= 0); + + QModelIndex home = model.index(QDir::homePath()); + view.setCurrentIndex(home); + view.selectAll(); + QVERIFY(view.selectionModel()->selectedIndexes().count() > 0); + + QModelIndex file; + for (int i = 0; i < model.rowCount(home); ++i) + if (!model.hasChildren(model.index(i, 0, home))) { + file = model.index(i, 0, home); + break; + } + view.setCurrentIndex(file); + view.selectAll(); + QVERIFY(view.selectionModel()->selectedIndexes().count() > 0); + + view.setCurrentIndex(QModelIndex()); + QVERIFY(view.selectionModel()->selectedIndexes().count() == 0); +} + +void tst_QColumnView::clicked() +{ + ColumnView view; + + QDirModel model; + view.setModel(&model); + view.resize(800,300); + view.show(); + + QModelIndex home = model.index(QDir::homePath()); + QVERIFY(home.isValid()); + view.setCurrentIndex(home); + QTest::qWait(ANIMATION_DELAY); + + QModelIndex parent = home.parent(); + QVERIFY(parent.isValid()); + + qRegisterMetaType<QModelIndex>("QModelIndex"); + QSignalSpy clickedSpy(&view, SIGNAL(clicked(const QModelIndex &))); + + QPoint localPoint = view.visualRect(home).center(); + QTest::mouseClick(view.viewport(), Qt::LeftButton, 0, localPoint); + QCOMPARE(clickedSpy.count(), 1); + qApp->processEvents(); + + if (sizeof(qreal) != sizeof(double)) { + QSKIP("Skipped due to rounding errors", SkipAll); + } + + for (int i = 0; i < view.createdColumns.count(); ++i) { + QAbstractItemView *column = view.createdColumns.at(i); + if (column && column->selectionModel() && (column->rootIndex() == home)) + QVERIFY(column->selectionModel()->selectedIndexes().isEmpty()); + } +} + +void tst_QColumnView::selectedColumns() +{ + ColumnView view; + QDirModel model; + view.setModel(&model); + view.resize(800,300); + view.show(); + + QModelIndex home = model.index(QDir::homePath()); + view.setCurrentIndex(home); + + QTest::qWait(ANIMATION_DELAY); + + for (int i = 0; i < view.createdColumns.count(); ++i) { + QAbstractItemView *column = view.createdColumns.at(i); + if (!column) + continue; + if (!column->rootIndex().isValid() || column->rootIndex() == home) + continue; + QTRY_VERIFY(column->currentIndex().isValid()); + } +} + +void tst_QColumnView::setSelection() +{ + ColumnView view; + // shouldn't do anything, it falls to the columns to handle this + QRect r; + view.setSelection(r, QItemSelectionModel::NoUpdate); +} + +void tst_QColumnView::setSelectionModel() +{ + ColumnView view; + QDirModel model; + view.setModel(&model); + view.show(); + + QModelIndex home = model.index(QDir::homePath()); + view.setCurrentIndex(home); + QTest::qWait(ANIMATION_DELAY); + + QItemSelectionModel *selectionModel = new QItemSelectionModel(&model); + view.setSelectionModel(selectionModel); + + bool found = false; + for (int i = 0; i < view.createdColumns.count(); ++i) { + if (view.createdColumns.at(i)->selectionModel() == selectionModel) { + found = true; + break; + } + } + QVERIFY(found); +} + +void tst_QColumnView::visualRegionForSelection() +{ + ColumnView view; + QItemSelection emptyItemSelection; + QCOMPARE(QRegion(), view.visualRegionForSelection(emptyItemSelection)); + + // a region that isn't empty + QDirModel model; + view.setModel(&model); + + // On Windows CE the home directory might actually be empty. +#ifndef Q_OS_WINCE + QString location = QDir::homePath(); +#else + QString location = QLatin1String("/Windows"); +#endif + + QModelIndex home = model.index(location); + QVERIFY(model.rowCount(home) > 1); + QItemSelection itemSelection(model.index(0, 0, home), model.index(model.rowCount(home) - 1, 0, home)); + QVERIFY(QRegion() != view.visualRegionForSelection(itemSelection)); +} + +void tst_QColumnView::moveGrip_basic() +{ + QColumnView view; + QColumnViewGrip *grip = new QColumnViewGrip(&view); + QSignalSpy spy(grip, SIGNAL(gripMoved(int))); + view.setCornerWidget(grip); + int oldX = view.width(); + grip->moveGrip(10); + QCOMPARE(oldX + 10, view.width()); + grip->moveGrip(-10); + QCOMPARE(oldX, view.width()); + grip->moveGrip(-800); + QVERIFY(view.width() == 0 || view.width() == 1); + grip->moveGrip(800); + view.setMinimumWidth(200); + grip->moveGrip(-800); + QCOMPARE(view.width(), 200); + QCOMPARE(spy.count(), 5); +} + +void tst_QColumnView::moveGrip_data() +{ + QTest::addColumn<bool>("reverse"); + QTest::newRow("normal") << false; + QTest::newRow("reverse") << true; +} + +void tst_QColumnView::moveGrip() +{ + QFETCH(bool, reverse); + if (reverse) + qApp->setLayoutDirection(Qt::RightToLeft); + QWidget topLevel; + ColumnView view(&topLevel); + TreeModel model; + view.setModel(&model); + QModelIndex home = model.thirdLevel(); + view.setCurrentIndex(home); + view.resize(640, 200); + topLevel.show(); + QTest::qWait(ANIMATION_DELAY); + + int columnNum = view.createdColumns.count() - 2; + QVERIFY(columnNum >= 0); + QObjectList list = view.createdColumns[columnNum]->children(); + QColumnViewGrip *grip = 0; + for (int i = 0; i < list.count(); ++i) { + if ((grip = qobject_cast<QColumnViewGrip *>(list[i]))) { + break; + } + } + if (!grip) + return; + + QAbstractItemView *column = qobject_cast<QAbstractItemView *>(grip->parent()); + int oldX = column->width(); + QCOMPARE(view.columnWidths().value(columnNum), oldX); + grip->moveGrip(10); + QCOMPARE(view.columnWidths().value(columnNum), (oldX + (reverse ? -10 : 10))); +} + +void tst_QColumnView::doubleClick() +{ + QColumnView view; + QColumnViewGrip *grip = new QColumnViewGrip(&view); + QSignalSpy spy(grip, SIGNAL(gripMoved(int))); + view.setCornerWidget(grip); + view.resize(200, 200); + QCOMPARE(view.width(), 200); + QTest::mouseDClick(grip, Qt::LeftButton); + QCOMPARE(view.width(), view.sizeHint().width()); + QCOMPARE(spy.count(), 1); +} + +void tst_QColumnView::gripMoved() +{ + QColumnView view; + QColumnViewGrip *grip = new QColumnViewGrip(&view); + QSignalSpy spy(grip, SIGNAL(gripMoved(int))); + view.setCornerWidget(grip); + view.move(300, 300); + view.resize(200, 200); + qApp->processEvents(); + + int oldWidth = view.width(); + + QTest::mousePress(grip, Qt::LeftButton, 0, QPoint(1,1)); + //QTest::mouseMove(grip, QPoint(grip->globalX()+50, y)); + + QPoint posNew = QPoint(grip->mapToGlobal(QPoint(1,1)).x() + 65, 0); + QMouseEvent *event = new QMouseEvent(QEvent::MouseMove, posNew, posNew, Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QCoreApplication::postEvent(grip, event); + QCoreApplication::processEvents(); + QTest::mouseRelease(grip, Qt::LeftButton); + + QCOMPARE(spy.count(), 1); + QCOMPARE(view.width(), oldWidth + 65); +} + +void tst_QColumnView::preview() +{ + QColumnView view; + QCOMPARE(view.previewWidget(), (QWidget*)0); + TreeModel model; + view.setModel(&model); + QCOMPARE(view.previewWidget(), (QWidget*)0); + QModelIndex home = model.index(0, 0); + QVERIFY(home.isValid()); + QVERIFY(model.hasChildren(home)); + view.setCurrentIndex(home); + QCOMPARE(view.previewWidget(), (QWidget*)0); + + QModelIndex file; + QVERIFY(model.rowCount(home) > 0); + for (int i = 0; i < model.rowCount(home); ++i) { + if (!model.hasChildren(model.index(i, 0, home))) { + file = model.index(i, 0, home); + break; + } + } + QVERIFY(file.isValid()); + view.setCurrentIndex(file); + QVERIFY(view.previewWidget() != (QWidget*)0); + + QWidget *previewWidget = new QWidget(&view); + view.setPreviewWidget(previewWidget); + QCOMPARE(view.previewWidget(), previewWidget); + QVERIFY(previewWidget->parent() != ((QWidget*)&view)); + view.setCurrentIndex(home); + + // previewWidget should be marked for deletion + QWidget *previewWidget2 = new QWidget(&view); + view.setPreviewWidget(previewWidget2); + QCOMPARE(view.previewWidget(), previewWidget2); +} + +void tst_QColumnView::swapPreview() +{ + // swap the preview widget in updatePreviewWidget + QColumnView view; + QStringList sl; + sl << QLatin1String("test"); + QStringListModel model(sl); + view.setModel(&model); + view.setCurrentIndex(view.indexAt(QPoint(1, 1))); + connect(&view, SIGNAL(updatePreviewWidget(const QModelIndex &)), + this, SLOT(setPreviewWidget())); + view.setCurrentIndex(view.indexAt(QPoint(1, 1))); + QTest::qWait(ANIMATION_DELAY); + qApp->processEvents(); +} + +void tst_QColumnView::setPreviewWidget() +{ + ((QColumnView*)sender())->setPreviewWidget(new QWidget); +} + +void tst_QColumnView::sizes() +{ + QColumnView view; + QCOMPARE(view.columnWidths().count(), 0); + + QList<int> newSizes; + newSizes << 10 << 4 << 50 << 6; + + QList<int> visibleSizes; + view.setColumnWidths(newSizes); + QCOMPARE(view.columnWidths(), visibleSizes); + + QDirModel model; + view.setModel(&model); + QModelIndex home = model.index(QDir::homePath()); + view.setCurrentIndex(home); + + QList<int> postSizes = view.columnWidths().mid(0, newSizes.count()); + QCOMPARE(postSizes, newSizes.mid(0, postSizes.count())); + + QVERIFY(view.columnWidths().count() > 1); + QList<int> smallerSizes; + smallerSizes << 6; + view.setColumnWidths(smallerSizes); + QList<int> expectedSizes = newSizes; + expectedSizes[0] = 6; + postSizes = view.columnWidths().mid(0, newSizes.count()); + QCOMPARE(postSizes, expectedSizes.mid(0, postSizes.count())); +} + +void tst_QColumnView::rowDelegate() +{ + ColumnView view; + QItemDelegate *d = new QItemDelegate; + view.setItemDelegateForRow(3, d); + + QDirModel model; + view.setModel(&model); + for (int i = 0; i < view.createdColumns.count(); ++i) { + QAbstractItemView *column = view.createdColumns.at(i); + QCOMPARE(column->itemDelegateForRow(3), (QAbstractItemDelegate*)d); + } + delete d; +} + +void tst_QColumnView::resize() +{ + QWidget topLevel; + ColumnView view(&topLevel); + QDirModel model; + view.setModel(&model); + view.resize(200, 200); + + topLevel.show(); + QModelIndex home = model.index(QDir::homePath()).parent(); + view.setCurrentIndex(home); + QTest::qWait(ANIMATION_DELAY); + view.resize(200, 300); + QTest::qWait(ANIMATION_DELAY); + + QVERIFY(view.horizontalScrollBar()->maximum() != 0); + view.resize(view.horizontalScrollBar()->maximum() * 10, 300); + QTest::qWait(ANIMATION_DELAY); + QVERIFY(view.horizontalScrollBar()->maximum() <= 0); +} + +void tst_QColumnView::changeSameColumn() +{ + ColumnView view; + TreeModel model; + view.setModel(&model); + QModelIndex second; + + QModelIndex home = model.secondLevel(); + //index(QDir::homePath()); + view.setCurrentIndex(home); + for (int i = 0; i < model.rowCount(home.parent()); ++i) { + QModelIndex idx = model.index(i, 0, home.parent()); + if (model.hasChildren(idx) && idx != home) { + second = idx; + break; + } + } + QVERIFY(second.isValid()); + + QList<QPointer<QAbstractItemView> > old = view.createdColumns; + view.setCurrentIndex(second); + + QCOMPARE(old, view.createdColumns); +} + +void tst_QColumnView::parentCurrentIndex_data() +{ + QTest::addColumn<int>("firstRow"); + QTest::addColumn<int>("secondRow"); + QTest::newRow("down") << 0 << 1; + QTest::newRow("up") << 1 << 0; +} + +void tst_QColumnView::parentCurrentIndex() +{ + QFETCH(int, firstRow); + QFETCH(int, secondRow); + + ColumnView view; + TreeModel model; + view.setModel(&model); + view.show(); + + QModelIndex first; + QModelIndex second; + QModelIndex third; + first = model.index(0, 0, QModelIndex()); + second = model.index(firstRow, 0, first); + third = model.index(0, 0, second); + QVERIFY(first.isValid()); + QVERIFY(second.isValid()); + QVERIFY(third.isValid()); + view.setCurrentIndex(third); + QTest::qWait(ANIMATION_DELAY); + QTRY_COMPARE(view.createdColumns[0]->currentIndex(), first); + QTRY_COMPARE(view.createdColumns[1]->currentIndex(), second); + QTRY_COMPARE(view.createdColumns[2]->currentIndex(), third); + + first = model.index(0, 0, QModelIndex()); + second = model.index(secondRow, 0, first); + third = model.index(0, 0, second); + QVERIFY(first.isValid()); + QVERIFY(second.isValid()); + QVERIFY(third.isValid()); + view.setCurrentIndex(third); + QTest::qWait(ANIMATION_DELAY); + QTRY_COMPARE(view.createdColumns[0]->currentIndex(), first); + QTRY_COMPARE(view.createdColumns[1]->currentIndex(), second); + QTRY_COMPARE(view.createdColumns[2]->currentIndex(), third); +} + +void tst_QColumnView::pullRug_data() +{ + QTest::addColumn<bool>("removeModel"); + QTest::newRow("model") << true; + QTest::newRow("index") << false; +} + +void tst_QColumnView::pullRug() +{ + QFETCH(bool, removeModel); + ColumnView view; + TreeModel model; + view.setModel(&model); + QModelIndex home = model.thirdLevel(); + view.setCurrentIndex(home); + if (removeModel) + view.setModel(0); + else + view.setCurrentIndex(QModelIndex()); + QTest::qWait(ANIMATION_DELAY); + // don't crash +} + +void tst_QColumnView::dynamicModelChanges() +{ + struct MyItemDelegate : public QItemDelegate + { + void paint(QPainter *painter, + const QStyleOptionViewItem &option, + const QModelIndex &index) const + { + paintedIndexes += index; + QItemDelegate::paint(painter, option, index); + } + + mutable QSet<QModelIndex> paintedIndexes; + + } delegate;; + QStandardItemModel model; + ColumnView view; + view.setModel(&model); + view.setItemDelegate(&delegate); + view.show(); + + QStandardItem *item = new QStandardItem(QLatin1String("item")); + model.appendRow(item); + + QTest::qWait(200); //let the time for painting to occur + QCOMPARE(delegate.paintedIndexes.count(), 1); + QCOMPARE(*delegate.paintedIndexes.begin(), model.index(0,0)); + + +} + + +QTEST_MAIN(tst_QColumnView) +#include "tst_qcolumnview.moc" + |