summaryrefslogtreecommitdiffstats
path: root/old/plugins/qtuitest_widgets/qtwidgets/testabstractitemview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'old/plugins/qtuitest_widgets/qtwidgets/testabstractitemview.cpp')
-rw-r--r--old/plugins/qtuitest_widgets/qtwidgets/testabstractitemview.cpp475
1 files changed, 475 insertions, 0 deletions
diff --git a/old/plugins/qtuitest_widgets/qtwidgets/testabstractitemview.cpp b/old/plugins/qtuitest_widgets/qtwidgets/testabstractitemview.cpp
new file mode 100644
index 0000000..ccb1371
--- /dev/null
+++ b/old/plugins/qtuitest_widgets/qtwidgets/testabstractitemview.cpp
@@ -0,0 +1,475 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of QtUiTest.
+**
+** $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 "testabstractitemview.h"
+#include "testwidgetslog.h"
+
+#include <QListView>
+#include <QTimer>
+#include <QScrollBar>
+#include <QComboBox>
+#include <QGraphicsProxyWidget>
+#include <QGraphicsView>
+
+#include <qtuitestnamespace.h>
+
+namespace QtUiTest {
+
+TestAbstractItemView::TestAbstractItemView(QObject *_q)
+ : TestWidget(_q), q(qobject_cast<QAbstractItemView*>(_q))
+{
+ if (q && q->parent() && qobject_cast<QComboBox*>(q->parent()->parent())) {
+ // The test object of the combobox will handle recording
+ return;
+ }
+
+ QtUiTest::connectFirst(q, SIGNAL(activated(QModelIndex)),
+ this, SLOT(on_activated(QModelIndex)));
+ QtUiTest::connectFirst(q, SIGNAL(pressed(QModelIndex)),
+ this, SLOT(on_activated(QModelIndex)));
+}
+
+void TestAbstractItemView::on_activated(QModelIndex const& ind)
+{
+ // Timer discourages duplicate signal emission.
+ if (m_lastActivatedTimer.elapsed() > 500 || m_lastActivatedTimer.elapsed() < 0) {
+ TestWidgetsLog() << "emit selected" << ind.data().toString();
+ emit selected(printable(ind.data().toString()));
+ m_lastActivatedTimer.start();
+ } else {
+ TestWidgetsLog() << "Would emit selected" << ind.data().toString()
+ << "except we have already done that recently.";
+ }
+}
+
+QString TestAbstractItemView::selectedText() const
+{
+ TestWidgetsLog();
+ return printable(q->currentIndex().data().toString());
+}
+
+QString TestAbstractItemView::text() const
+{
+ TestWidgetsLog();
+ return list().join("\n");
+}
+
+QStringList TestAbstractItemView::list() const
+{
+ class QModelListGetter : public QModelViewIterator<QAbstractItemView>
+ {
+ public:
+ QModelListGetter(QAbstractItemView *view)
+ : QModelViewIterator<QAbstractItemView>(view) {};
+
+ QStringList getList() {
+ list.clear();
+ iterate(view()->rootIndex());
+ return list;
+ }
+ protected:
+ virtual void visit(QModelIndex const &index)
+ { list << itemForIndex(index); }
+
+ QStringList list;
+ };
+
+ return QModelListGetter(q).getList();
+}
+
+QModelIndex TestAbstractItemView::indexForItem(QString const &item) const
+{
+ QModelIndex ret;
+
+ class QModelIndexGetter : public QModelViewIterator<QAbstractItemView>
+ {
+ public:
+ QModelIndexGetter(QAbstractItemView *view, QString const &item)
+ : QModelViewIterator<QAbstractItemView>(view), matches(0), m_item(item) {};
+ QModelIndex index;
+ int matches;
+
+ protected:
+ void visit(QModelIndex const &idx) {
+
+ if (itemForIndex(idx) == m_item) {
+ ++matches;
+ index = idx;
+ }
+ }
+ private:
+ QString m_item;
+ };
+
+ QModelIndexGetter indexGetter(q, item);
+ indexGetter.iterate(q->rootIndex());
+
+ // No matching item
+ if (!indexGetter.matches) {
+ TestWidgetsLog() << "no matching item for" << item;
+ }
+
+ // More than one matching item
+ else if (indexGetter.matches > 1) {
+ qWarning("QtUitest: more than one item matches '%s' in item view", qPrintable(item));
+ TestWidgetsLog() << indexGetter.matches << "matches for" << item;
+ }
+
+ else
+ ret = indexGetter.index;
+
+ return ret;
+}
+
+QModelIndex TestAbstractItemView::indexFromList(QVariantList const &list) const
+{
+ QVariantList indexList = list;
+ QModelIndex ret;
+ if (list.size() > 1) {
+ int column = indexList.takeLast().toInt();
+ int row = indexList.takeLast().toInt();
+ ret = q->model()->index(row, column, indexFromList(indexList));
+ }
+ return ret;
+}
+
+
+QVariantList TestAbstractItemView::listFromIndex(QModelIndex const &index) const
+{
+ QVariantList ret;
+ if (index.parent().isValid()) {
+ ret << listFromIndex(index.parent());
+ }
+ if (index.isValid()) {
+ ret << index.row() << index.column();
+ }
+
+ return ret;
+}
+
+QRect TestAbstractItemView::visualRect(QString const &item) const
+{
+ QRect ret;
+
+ QModelIndex index = indexForItem(item);
+
+ if (index.isValid()) {
+ ret = q->visualRect(index);
+ ret.moveTopLeft(q->mapFromGlobal(q->viewport()->mapToGlobal(ret.topLeft())));
+ }
+
+ return ret;
+}
+
+bool TestAbstractItemView::isMultiSelection() const
+{ return (q->selectionMode() > QAbstractItemView::SingleSelection); }
+
+bool TestAbstractItemView::canSelect(QString const &item) const
+{
+ if (q->selectionMode() == QAbstractItemView::NoSelection)
+ return false;
+
+ return list().contains(item);
+}
+
+bool TestAbstractItemView::canSelectMulti(QStringList const &items) const
+{
+ if (!isMultiSelection())
+ return false;
+
+ QSet<QString> itemSet = items.toSet();
+ return ((itemSet & list().toSet()) == itemSet);
+}
+
+bool TestAbstractItemView::select(QString const &item)
+{
+ TestWidgetsLog() << item;
+
+ if (!canSelect(item)) {
+ TestWidgetsLog() << "can't select" << item;
+ return false;
+ }
+
+ if (!QtUiTest::mousePreferred() && (!setFocus() || !hasFocus())) {
+ QtUiTest::setErrorString("Couldn't give focus to item view");
+ return false;
+ }
+
+ return select(indexForItem(item));
+}
+
+bool TestAbstractItemView::select(QModelIndex const &index)
+{
+ if (QtUiTest::mousePreferred()) {
+ if (!ensureVisible(index)) {
+ TestWidgetsLog() << "couldn't make item visible";
+ return false;
+ }
+ QPoint pos = q->visualRect(index).center();
+ TestWidgetsLog() << "after ensureVisible, item is at" << pos;
+
+ while (q->parentWidget()) {
+ // Workaround to allow selection from QComboBoxes embedded in a QGraphicsView
+ QGraphicsProxyWidget *gpw = q->parentWidget()->graphicsProxyWidget();
+ if (!gpw) break;
+ QGraphicsScene *scene = gpw->scene();
+ if (!scene) break;
+ QGraphicsView *view = scene->views().first();
+ if (!view) break;
+ QtUiTest::mouseClick(view->mapToGlobal(view->mapFromScene(gpw->mapToScene(pos))), Qt::LeftButton);
+ return true;
+ }
+
+ QtUiTest::mouseClick(q->viewport()->mapToGlobal(pos), Qt::LeftButton);
+ return true;
+
+ } else {
+ // Consume pending key events, if any.
+ while (QtUiTest::waitForEvent(q, QEvent::KeyRelease, 200, Qt::QueuedConnection))
+ {}
+
+ const int maxtries = 100;
+
+ // Move vertically
+ int desiredY = q->visualRect(index).center().y();
+ int currentY = q->visualRect(q->currentIndex()).center().y();
+
+ for (int i = 0; i < maxtries && desiredY != currentY; ++i) {
+ Qt::Key key;
+ if (desiredY < currentY) {
+ key = Qt::Key_Up;
+ TestWidgetsLog() << "Up (desired=" << desiredY << ", current=" << currentY << ")";
+ } else {
+ key = Qt::Key_Down;
+ TestWidgetsLog() << "Down (desired=" << desiredY << ", current=" << currentY << ")";
+ }
+ if (!QtUiTest::keyClick(q, key)) return false;
+ desiredY = q->visualRect(index).center().y();
+ currentY = q->visualRect(q->currentIndex()).center().y();
+ }
+ if (desiredY != currentY) {
+ QtUiTest::setErrorString(QString(
+ "Up/down keys failed to move highlight vertically; desired position %1, "
+ "current position %2").arg(desiredY).arg(currentY));
+ return false;
+ }
+
+ // Move horizontally
+ int desiredX = q->visualRect(index).center().x();
+ int currentX = q->visualRect(q->currentIndex()).center().x();
+
+ for (int i = 0; i < maxtries && desiredX != currentX; ++i) {
+ Qt::Key key;
+ if (desiredX < currentX) {
+ key = Qt::Key_Left;
+ TestWidgetsLog() << "Left (desired=" << desiredX << ", current=" << currentX << ")";
+ } else {
+ key = Qt::Key_Right;
+ TestWidgetsLog() << "Right (desired=" << desiredX << ", current=" << currentX << ")";
+ }
+ if (!QtUiTest::keyClick(q, key)) return false;
+ desiredX = q->visualRect(index).center().x();
+ currentX = q->visualRect(q->currentIndex()).center().x();
+ }
+ if (desiredX != currentX) {
+ QtUiTest::setErrorString(QString(
+ "Left/right keys failed to move highlight horizontally; desired position %1, "
+ "current position %2").arg(desiredX).arg(currentX));
+ return false;
+ }
+
+ TestWidgetsLog() << "hit activate key";
+ if (!QtUiTest::keyClick(q, QtUiTest::Key_Activate)) return false;
+ return true;
+ }
+
+ return false;
+}
+
+bool TestAbstractItemView::selectMulti(QStringList const &items)
+{
+ if (!canSelectMulti(items)) return false;
+
+ TestWidgetsLog() << items;
+
+ return false;
+}
+
+bool TestAbstractItemView::selectIndex(QVariantList const &indexList)
+{
+ QModelIndex idx = indexFromList(indexList);
+ if (idx.isValid()) {
+ return select(idx);
+ }
+ else {
+ QtUiTest::setErrorString("Invalid index");
+ return false;
+ }
+}
+
+QVariantList TestAbstractItemView::selectedIndex() const
+{
+ return listFromIndex(q->currentIndex());
+}
+
+bool TestAbstractItemView::ensureVisible(QString const &item)
+{
+ return ensureVisible(indexForItem(item));
+}
+
+bool TestAbstractItemView::ensureVisible(QModelIndex const &index)
+{
+ QPoint p = q->visualRect(index).center();
+
+ if (q->viewport()->rect().contains(p)) {
+ TestWidgetsLog() << "item is already visible";
+ return true;
+ }
+
+ if (!QtUiTest::mousePreferred())
+ return false;
+
+ /* Figure out the points to click for scrolling in each direction */
+ QScrollBar *vbar = q->verticalScrollBar();
+ QScrollBar *hbar = q->horizontalScrollBar();
+ QPoint up = vbar->mapToGlobal(QPoint(vbar->width()/2,5));
+ QPoint down = vbar->mapToGlobal(QPoint(vbar->width()/2,vbar->height()-5));
+ QPoint left = hbar->mapToGlobal(QPoint(5, hbar->height()/2));
+ QPoint right = hbar->mapToGlobal(QPoint(hbar->width()-5,hbar->height()/2));
+
+ // While p is above rect...
+ while (p.y() < q->viewport()->rect().top()) {
+ if (!vbar->isVisible()) return false;
+ TestWidgetsLog() << "up" << "\nrect:" << rect() << "p:" << p;
+ QtUiTest::mouseClick(up);
+ waitForSignal(vbar, SIGNAL(valueChanged(int)));
+ p = q->visualRect(index).center();
+ }
+ // While p is below rect...
+ while (p.y() > q->viewport()->rect().bottom()) {
+ if (!vbar->isVisible()) return false;
+ TestWidgetsLog() << "down" << "\nrect:" << rect() << "p:" << p;
+ QtUiTest::mouseClick(down);
+ waitForSignal(vbar, SIGNAL(valueChanged(int)));
+ p = q->visualRect(index).center();
+ }
+ // While p is left of rect...
+ while (p.x() < q->viewport()->rect().left()) {
+ if (!hbar->isVisible()) return false;
+ TestWidgetsLog() << "left" << "\nrect:" << rect() << "p:" << p;
+ QtUiTest::mouseClick(left);
+ waitForSignal(hbar, SIGNAL(valueChanged(int)));
+ p = q->visualRect(index).center();
+ }
+ // While p is right of rect...
+ while (p.x() > q->viewport()->rect().right()) {
+ if (!hbar->isVisible()) return false;
+ TestWidgetsLog() << "right" << "\nrect:" << rect() << "p:" << p;
+ QtUiTest::mouseClick(right);
+ waitForSignal(hbar, SIGNAL(valueChanged(int)));
+ p = q->visualRect(index).center();
+ }
+
+ if (!q->viewport()->rect().contains(p)) {
+ TestWidgetsLog() << "failed" << "\nrect:" << q->viewport()->rect() << "p:" << p;
+ return false;
+ }
+
+ return true;
+}
+
+bool TestAbstractItemView::canEnter(QVariant const& item) const
+{
+ bool ret = false;
+ QModelIndex ci = q->currentIndex();
+ if (ci.isValid() && q->selectionMode() != QAbstractItemView::NoSelection && ci.flags() & Qt::ItemIsEditable) {
+ QWidget *indexWidget = q->indexWidget(ci);
+ if (!indexWidget) {
+ // FIXME: Should simulate correct events to enter edit mode
+ q->edit(ci);
+ indexWidget = q->indexWidget(ci);
+ }
+ InputWidget* iw = qtuitest_cast<InputWidget*>(indexWidget);
+ if (iw) {
+ ret = iw->canEnter(item);
+ // FIXME: Should simulate correct events to leave edit mode
+ q->setFocus();
+ } else {
+ SelectWidget* sw = qtuitest_cast<SelectWidget*>(indexWidget);
+ if (sw) {
+ ret = sw->canSelect(item.toString());
+ q->setFocus();
+ }
+ }
+ }
+ return ret;
+}
+
+bool TestAbstractItemView::enter(QVariant const& item, bool noCommit)
+{
+ bool ret = false;
+ QModelIndex ci = q->currentIndex();
+ if (ci.isValid() && q->selectionMode() != QAbstractItemView::NoSelection && ci.flags() & Qt::ItemIsEditable) {
+ QWidget *indexWidget = q->indexWidget(ci);
+ if (!indexWidget) {
+ // FIXME: Should simulate correct events to enter edit mode
+ q->edit(ci);
+ indexWidget = q->indexWidget(ci);
+ }
+ InputWidget* iw = qtuitest_cast<InputWidget*>(indexWidget);
+ if (iw) {
+ ret = iw->enter(item, noCommit);
+ // FIXME: Should simulate correct events to leave edit mode
+ q->setFocus();
+ } else {
+ SelectWidget* sw = qtuitest_cast<SelectWidget*>(indexWidget);
+ ret = sw->select(item.toString());
+ q->setFocus();
+ }
+ }
+
+ return ret;
+}
+
+bool TestAbstractItemView::canWrap(QObject* o)
+{ return qobject_cast<QAbstractItemView*>(o); }
+
+}