38be0d1383
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
1044 lines
30 KiB
C++
1044 lines
30 KiB
C++
/****************************************************************************
|
|
**
|
|
** 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$
|
|
** No Commercial Usage
|
|
** This file contains pre-release code and may not be distributed.
|
|
** You may use this file in accordance with the terms and conditions
|
|
** contained in the Technology Preview License Agreement accompanying
|
|
** this package.
|
|
**
|
|
** GNU Lesser General Public License Usage
|
|
** Alternatively, 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.
|
|
**
|
|
** If you have questions regarding the use of this file, please contact
|
|
** Nokia at qt-info@nokia.com.
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
**
|
|
** $QT_END_LICENSE$
|
|
**
|
|
****************************************************************************/
|
|
|
|
|
|
#include <QtTest/QtTest>
|
|
#include <qstandarditemmodel.h>
|
|
#include <qitemdelegate.h>
|
|
#include <qcolumnview.h>
|
|
#include "../../../src/gui/itemviews/qcolumnviewgrip_p.h"
|
|
#ifndef Q_OS_SYMBIAN
|
|
#include "../../../src/gui/dialogs/qfilesystemmodel_p.h"
|
|
#endif
|
|
#include <qdirmodel.h>
|
|
#include <qstringlistmodel.h>
|
|
#include <qdebug.h>
|
|
#include <qitemdelegate.h>
|
|
#include <qscrollbar.h>
|
|
#include <private/qcolumnview_p.h>
|
|
#include "../../shared/util.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"
|
|
|