summaryrefslogtreecommitdiffstats
path: root/tests/auto/qtreewidget
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /tests/auto/qtreewidget
Initial import from the monolithic Qt.
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
Diffstat (limited to 'tests/auto/qtreewidget')
-rw-r--r--tests/auto/qtreewidget/.gitignore1
-rw-r--r--tests/auto/qtreewidget/qtreewidget.pro4
-rw-r--r--tests/auto/qtreewidget/tst_qtreewidget.cpp3352
3 files changed, 3357 insertions, 0 deletions
diff --git a/tests/auto/qtreewidget/.gitignore b/tests/auto/qtreewidget/.gitignore
new file mode 100644
index 0000000000..08c63b4b52
--- /dev/null
+++ b/tests/auto/qtreewidget/.gitignore
@@ -0,0 +1 @@
+tst_qtreewidget
diff --git a/tests/auto/qtreewidget/qtreewidget.pro b/tests/auto/qtreewidget/qtreewidget.pro
new file mode 100644
index 0000000000..bc38239c6f
--- /dev/null
+++ b/tests/auto/qtreewidget/qtreewidget.pro
@@ -0,0 +1,4 @@
+load(qttest_p4)
+SOURCES += tst_qtreewidget.cpp
+
+
diff --git a/tests/auto/qtreewidget/tst_qtreewidget.cpp b/tests/auto/qtreewidget/tst_qtreewidget.cpp
new file mode 100644
index 0000000000..7addcfd5af
--- /dev/null
+++ b/tests/auto/qtreewidget/tst_qtreewidget.cpp
@@ -0,0 +1,3352 @@
+/****************************************************************************
+**
+** 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 <qtreewidget.h>
+#include <qtreewidgetitemiterator.h>
+#include <qapplication.h>
+#include <qeventloop.h>
+#include <qdebug.h>
+#include <qheaderview.h>
+#include <qlineedit.h>
+#include <QScrollBar>
+#include <QStyledItemDelegate>
+
+#include "../../shared/util.h"
+
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class CustomTreeWidget : public QTreeWidget
+{
+ Q_OBJECT
+public:
+ QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const
+ { return QTreeWidget::indexFromItem(item, column); }
+};
+
+class tst_QTreeWidget : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QTreeWidget();
+ ~tst_QTreeWidget();
+
+
+public slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void init();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void addTopLevelItem();
+ void currentItem_data();
+ void currentItem();
+ void editItem_data();
+ void editItem();
+ void takeItem_data();
+ void takeItem();
+ void removeChild_data();
+ void removeChild();
+ void setItemHidden();
+ void setItemHidden2();
+ void selectedItems_data();
+ void selectedItems();
+ void itemAssignment();
+ void clone_data();
+ void clone();
+ void expand_data();
+ void expand();
+ void checkState_data();
+ void checkState();
+ void findItems_data();
+ void findItems();
+ void findItemsInColumn();
+ void sortItems_data();
+ void sortItems();
+ void deleteItems_data();
+ void deleteItems();
+ void itemAboveOrBelow();
+ void itemStreaming_data();
+ void itemStreaming();
+ void insertTopLevelItems_data();
+ void insertTopLevelItems();
+ void keyboardNavigation();
+ void scrollToItem();
+ void setSortingEnabled();
+ void match();
+ void columnCount();
+ void setHeaderLabels();
+ void setHeaderItem();
+ void itemWidget_data();
+ void itemWidget();
+ void insertItemsWithSorting_data();
+ void insertItemsWithSorting();
+ void insertExpandedItemsWithSorting_data();
+ void insertExpandedItemsWithSorting();
+ void changeDataWithSorting_data();
+ void changeDataWithSorting();
+ void changeDataWithStableSorting_data();
+ void changeDataWithStableSorting();
+
+ void sortedIndexOfChild_data();
+ void sortedIndexOfChild();
+ void defaultRowSizes();
+
+ void task191552_rtl();
+ void task203673_selection();
+ void rootItemFlags();
+ void task218661_setHeaderData();
+ void task245280_sortChildren();
+ void task253109_itemHeight();
+
+ // QTreeWidgetItem
+ void itemOperatorLessThan();
+ void addChild();
+ void setData();
+ void enableDisable();
+
+ void expandAndCallapse();
+ void itemData();
+ void setDisabled();
+ void removeSelectedItem();
+ void removeCurrentItem();
+ void removeCurrentItem_task186451();
+ void randomExpand();
+ void crashTest();
+ void sortAndSelect();
+
+ void task206367_duplication();
+ void selectionOrder();
+
+ void setSelectionModel();
+ void task217309();
+ void setCurrentItemExpandsParent();
+ void task239150_editorWidth();
+ void setTextUpdate();
+ void taskQTBUG2844_visualItemRect();
+ void setChildIndicatorPolicy();
+
+
+public slots:
+ void itemSelectionChanged();
+ void emitDataChanged();
+
+private:
+ CustomTreeWidget *testWidget;
+};
+
+// Testing get/set functions
+void tst_QTreeWidget::getSetCheck()
+{
+ QTreeWidget obj1;
+ // int QTreeWidget::columnCount()
+ // void QTreeWidget::setColumnCount(int)
+ obj1.setColumnCount(0);
+ QCOMPARE(obj1.columnCount(), 0);
+
+ obj1.setColumnCount(INT_MIN);
+ QCOMPARE(obj1.columnCount(), 0);
+
+ //obj1.setColumnCount(INT_MAX);
+ //QCOMPARE(obj1.columnCount(), INT_MAX);
+ // Since setColumnCount allocates memory, there is no way this will succeed
+
+ obj1.setColumnCount(100);
+ QCOMPARE(obj1.columnCount(), 100);
+
+ // QTreeWidgetItem * QTreeWidget::headerItem()
+ // void QTreeWidget::setHeaderItem(QTreeWidgetItem *)
+ QTreeWidgetItem *var2 = new QTreeWidgetItem();
+ obj1.setHeaderItem(var2);
+ QCOMPARE(obj1.headerItem(), var2);
+
+ obj1.setHeaderItem((QTreeWidgetItem *)0);
+// QCOMPARE(obj1.headerItem(), (QTreeWidgetItem *)0);
+
+ // QTreeWidgetItem * QTreeWidget::currentItem()
+ // void QTreeWidget::setCurrentItem(QTreeWidgetItem *)
+ QTreeWidgetItem *var3 = new QTreeWidgetItem(&obj1);
+ obj1.setCurrentItem(var3);
+ QCOMPARE(obj1.currentItem(), var3);
+
+ obj1.setCurrentItem((QTreeWidgetItem *)0);
+ QCOMPARE(obj1.currentItem(), (QTreeWidgetItem *)0);
+}
+
+typedef QList<int> IntList;
+typedef QList<IntList> ListIntList;
+
+Q_DECLARE_METATYPE(IntList)
+Q_DECLARE_METATYPE(ListIntList)
+Q_DECLARE_METATYPE(QModelIndex)
+Q_DECLARE_METATYPE(Qt::Orientation)
+
+typedef QTreeWidgetItem TreeItem;
+typedef QList<TreeItem*> TreeItemList;
+
+Q_DECLARE_METATYPE(QTreeWidgetItem*)
+Q_DECLARE_METATYPE(TreeItemList)
+
+tst_QTreeWidget::tst_QTreeWidget(): testWidget(0)
+{
+}
+
+tst_QTreeWidget::~tst_QTreeWidget()
+{
+}
+
+void tst_QTreeWidget::initTestCase()
+{
+ qMetaTypeId<QModelIndex>();
+ qMetaTypeId<Qt::Orientation>();
+ qRegisterMetaType<QTreeWidgetItem*>("QTreeWidgetItem*");
+
+ testWidget = new CustomTreeWidget();
+ testWidget->show();
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(testWidget);
+#endif
+}
+
+void tst_QTreeWidget::cleanupTestCase()
+{
+ testWidget->hide();
+ delete testWidget;
+}
+
+void tst_QTreeWidget::init()
+{
+ testWidget->clear();
+ testWidget->setColumnCount(2);
+}
+
+void tst_QTreeWidget::cleanup()
+{
+}
+
+TreeItem *operator<<(TreeItem *parent, const TreeItemList &children) {
+ for (int i = 0; i < children.count(); ++i)
+ parent->addChild(children.at(i));
+ return parent;
+}
+
+static void populate(QTreeWidget *widget, const TreeItemList &topLevelItems,
+ TreeItem *headerItem = 0)
+{
+ widget->clear();
+ widget->setHeaderItem(headerItem);
+ foreach (TreeItem *item, topLevelItems)
+ widget->addTopLevelItem(item);
+}
+
+void tst_QTreeWidget::addTopLevelItem()
+{
+ QTreeWidget tree;
+ QCOMPARE(tree.topLevelItemCount(), 0);
+
+ // try to add 0
+ tree.addTopLevelItem(0);
+ QCOMPARE(tree.topLevelItemCount(), 0);
+ QCOMPARE(tree.indexOfTopLevelItem(0), -1);
+
+ // add one at a time
+ QList<TreeItem*> tops;
+ for (int i = 0; i < 10; ++i) {
+ TreeItem *ti = new TreeItem();
+ QCOMPARE(tree.indexOfTopLevelItem(ti), -1);
+ tree.addTopLevelItem(ti);
+ QCOMPARE(tree.topLevelItemCount(), i+1);
+ QCOMPARE(tree.topLevelItem(i), ti);
+ QCOMPARE(tree.topLevelItem(-1), static_cast<TreeItem*>(0));
+ QCOMPARE(tree.indexOfTopLevelItem(ti), i);
+ QCOMPARE(ti->parent(), static_cast<TreeItem*>(0));
+ tree.addTopLevelItem(ti);
+ QCOMPARE(tree.topLevelItemCount(), i+1);
+ tops.append(ti);
+ }
+
+ // delete one at a time
+ while (!tops.isEmpty()) {
+ TreeItem *ti = tops.takeFirst();
+ delete ti;
+ QCOMPARE(tree.topLevelItemCount(), tops.count());
+ for (int i = 0; i < tops.count(); ++i)
+ QCOMPARE(tree.topLevelItem(i), tops.at(i));
+ }
+
+ // add none
+ {
+ int count = tree.topLevelItemCount();
+ tree.addTopLevelItems(tops);
+ QCOMPARE(tree.topLevelItemCount(), count);
+ }
+
+ // add many at a time
+ {
+ const int count = 10;
+ for (int i = 0; i < 100; i += count) {
+ tops.clear();
+ for (int j = 0; j < count; ++j)
+ tops << new TreeItem(QStringList() << QString("%0").arg(j));
+ tree.addTopLevelItems(tops);
+ QCOMPARE(tree.topLevelItemCount(), count + i);
+ for (int j = 0; j < count; ++j)
+ QCOMPARE(tree.topLevelItem(i+j), tops.at(j));
+
+ tree.addTopLevelItems(tops);
+ QCOMPARE(tree.topLevelItemCount(), count + i);
+ }
+ }
+
+ // insert
+ {
+ tops.clear();
+ for (int i = 0; i < 10; ++i)
+ tops << new TreeItem();
+ int count = tree.topLevelItemCount();
+ tree.insertTopLevelItems(100000, tops);
+ // ### fixme
+ QCOMPARE(tree.topLevelItemCount(), count + 10);
+ }
+}
+
+void tst_QTreeWidget::currentItem_data()
+{
+ QTest::addColumn<TreeItemList>("topLevelItems");
+
+ QTest::newRow("only top-level items, 2 columns")
+ << (TreeItemList()
+ << new TreeItem(QStringList() << "a" << "b")
+ << new TreeItem(QStringList() << "c" << "d"));
+ TreeItemList lst;
+ lst << (new TreeItem(QStringList() << "a" << "b")
+ << (TreeItemList()
+ << new TreeItem(QStringList() << "c" << "d")
+ << new TreeItem(QStringList() << "c" << "d")
+ )
+ )
+ << (new TreeItem(QStringList() << "e" << "f")
+ << (TreeItemList()
+ << new TreeItem(QStringList() << "g" << "h")
+ << new TreeItem(QStringList() << "g" << "h")
+ )
+ );
+ QTest::newRow("hierarchy, 2 columns") << lst;
+}
+
+void tst_QTreeWidget::currentItem()
+{
+ QFETCH(TreeItemList, topLevelItems);
+
+ QTreeWidget tree;
+ tree.show();
+ populate(&tree, topLevelItems, new TreeItem(QStringList() << "1" << "2"));
+ QTreeWidgetItem *previous = 0;
+ for (int x = 0; x < 2; ++x) {
+ tree.setSelectionBehavior(x ? QAbstractItemView::SelectItems
+ : QAbstractItemView::SelectRows);
+ QSignalSpy currentItemChangedSpy(
+ &tree, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ QSignalSpy itemSelectionChangedSpy(
+ &tree, SIGNAL(itemSelectionChanged()));
+
+ QTreeWidgetItemIterator it(&tree);
+ // do all items
+ while (QTreeWidgetItem *item = (*it++)) {
+ tree.setCurrentItem(item);
+ QCOMPARE(tree.currentItem(), item);
+
+ QCOMPARE(currentItemChangedSpy.count(), 1);
+ QVariantList args = currentItemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(1)), previous);
+
+ QCOMPARE(itemSelectionChangedSpy.count(), 1);
+ itemSelectionChangedSpy.clear();
+
+ previous = item;
+ // do all columns
+ for (int col = 0; col < item->columnCount(); ++col) {
+ tree.setCurrentItem(item, col);
+ QCOMPARE(tree.currentItem(), item);
+ QCOMPARE(tree.currentColumn(), col);
+
+ if (!currentItemChangedSpy.isEmpty()) {
+ // ### we get a currentItemChanged() when what really
+ // changed was just currentColumn(). Should it be like this?
+ QCOMPARE(currentItemChangedSpy.count(), 1);
+ QVariantList args = currentItemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(1)), item);
+ if (tree.selectionBehavior() == QAbstractItemView::SelectItems) {
+ QCOMPARE(itemSelectionChangedSpy.count(), 1);
+ itemSelectionChangedSpy.clear();
+ } else {
+ QCOMPARE(itemSelectionChangedSpy.count(), 0);
+ }
+ }
+ }
+ }
+ }
+
+ // can't set the headerItem to be the current item
+ tree.setCurrentItem(tree.headerItem());
+ QCOMPARE(tree.currentItem(), static_cast<TreeItem*>(0));
+}
+
+void tst_QTreeWidget::editItem_data()
+{
+ QTest::addColumn<TreeItemList>("topLevelItems");
+
+ {
+ TreeItemList list;
+ for (int i = 0; i < 10; i++) {
+ TreeItem *item = new TreeItem(QStringList() << "col1" << "col2");
+ if ((i & 1) == 0)
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ else
+ item->setFlags(item->flags() & ~Qt::ItemIsEditable);
+ list << item;
+ }
+ QTest::newRow("2 columns, only even items editable")
+ << list;
+ }
+}
+
+void tst_QTreeWidget::editItem()
+{
+ QFETCH(TreeItemList, topLevelItems);
+
+ QTreeWidget tree;
+ populate(&tree, topLevelItems, new TreeItem(QStringList() << "1" << "2"));
+ tree.show();
+ QTest::qWaitForWindowShown(&tree);
+
+ QSignalSpy itemChangedSpy(
+ &tree, SIGNAL(itemChanged(QTreeWidgetItem*,int)));
+
+ QTreeWidgetItemIterator it(&tree);
+ while (QTreeWidgetItem *item = (*it++)) {
+ for (int col = 0; col < item->columnCount(); ++col) {
+ if (!(item->flags() & Qt::ItemIsEditable))
+ QTest::ignoreMessage(QtWarningMsg, "edit: editing failed");
+ tree.editItem(item, col);
+ QApplication::instance()->processEvents();
+ QApplication::instance()->processEvents();
+ QLineEdit *editor = qFindChild<QLineEdit*>(&tree);
+ if (editor) {
+ QVERIFY(item->flags() & Qt::ItemIsEditable);
+ QCOMPARE(editor->selectedText(), editor->text());
+ QTest::keyClick(editor, Qt::Key_A);
+ QTest::keyClick(editor, Qt::Key_Enter);
+ QApplication::instance()->processEvents();
+ QCOMPARE(itemChangedSpy.count(), 1);
+ QVariantList args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), col);
+ } else {
+ QVERIFY(!(item->flags() & Qt::ItemIsEditable));
+ }
+ }
+ }
+}
+
+void tst_QTreeWidget::takeItem_data()
+{
+ QTest::addColumn<int>("index");
+ QTest::addColumn<bool>("topLevel");
+ QTest::addColumn<bool>("outOfBounds");
+
+ QTest::newRow("First, topLevel") << 0 << true << false;
+ QTest::newRow("Last, topLevel") << 2 << true << false;
+ QTest::newRow("Middle, topLevel") << 1 << true << false;
+ QTest::newRow("Out of bounds, toplevel, (index: -1)") << -1 << true << true;
+ QTest::newRow("Out of bounds, toplevel, (index: 3)") << 3 << true << true;
+
+ QTest::newRow("First, child of topLevel") << 0 << false << false;
+ QTest::newRow("Last, child of topLevel") << 2 << false << false;
+ QTest::newRow("Middle, child of topLevel") << 1 << false << false;
+ QTest::newRow("Out of bounds, child of toplevel, (index: -1)") << -1 << false << true;
+ QTest::newRow("Out of bounds, child of toplevel, (index: 3)") << 3 << false << true;
+}
+
+void tst_QTreeWidget::takeItem()
+{
+ QFETCH(int, index);
+ QFETCH(bool, topLevel);
+ QFETCH(bool, outOfBounds);
+
+ for (int i=0; i<3; ++i) {
+ QTreeWidgetItem *top = new QTreeWidgetItem(testWidget);
+ top->setText(0, QString("top%1").arg(i));
+ for (int j=0; j<3; ++j) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(top);
+ child->setText(0, QString("child%1").arg(j));
+ }
+ }
+
+ QCOMPARE(testWidget->topLevelItemCount(), 3);
+ QCOMPARE(testWidget->topLevelItem(0)->childCount(), 3);
+
+ if (topLevel) {
+ int count = testWidget->topLevelItemCount();
+ QTreeWidgetItem *item = testWidget->takeTopLevelItem(index);
+ if (outOfBounds) {
+ QCOMPARE(item, (QTreeWidgetItem *)0);
+ QCOMPARE(count, testWidget->topLevelItemCount());
+ } else {
+ QCOMPARE(item->text(0), QString("top%1").arg(index));
+ QCOMPARE(count-1, testWidget->topLevelItemCount());
+ delete item;
+ }
+ } else {
+ int count = testWidget->topLevelItem(0)->childCount();
+ QTreeWidgetItem *item = testWidget->topLevelItem(0)->takeChild(index);
+ if (outOfBounds) {
+ QCOMPARE(item, (QTreeWidgetItem *)0);
+ QCOMPARE(count, testWidget->topLevelItem(0)->childCount());
+ } else {
+ QCOMPARE(item->text(0), QString("child%1").arg(index));
+ QCOMPARE(count-1, testWidget->topLevelItem(0)->childCount());
+ delete item;
+ }
+ }
+}
+
+void tst_QTreeWidget::removeChild_data()
+{
+ QTest::addColumn<int>("childCount");
+ QTest::addColumn<int>("removeAt");
+
+ QTest::newRow("10 remove 3") << 10 << 3;
+}
+
+void tst_QTreeWidget::removeChild()
+{
+ QFETCH(int, childCount);
+ QFETCH(int, removeAt);
+
+ QTreeWidgetItem *root = new QTreeWidgetItem;
+ for (int i = 0; i < childCount; ++i)
+ new QTreeWidgetItem(root, QStringList(QString::number(i)));
+
+ QCOMPARE(root->childCount(), childCount);
+ for (int j = 0; j < childCount; ++j)
+ QCOMPARE(root->child(j)->text(0), QString::number(j));
+
+ QTreeWidgetItem *remove = root->child(removeAt);
+ root->removeChild(remove);
+
+ QCOMPARE(root->childCount(), childCount - 1);
+ for (int k = 0; k < childCount; ++k) {
+ if (k == removeAt)
+ QCOMPARE(remove->text(0), QString::number(k));
+ else if (k < removeAt)
+ QCOMPARE(root->child(k)->text(0), QString::number(k));
+ else if (k > removeAt)
+ QCOMPARE(root->child(k - 1)->text(0), QString::number(k));
+ }
+ delete root;
+}
+
+void tst_QTreeWidget::setItemHidden()
+{
+ QTreeWidgetItem *parent = new QTreeWidgetItem(testWidget);
+ parent->setText(0, "parent");
+ QTreeWidgetItem *child = new QTreeWidgetItem(parent);
+ child->setText(0, "child");
+ QVERIFY(child->parent());
+
+ testWidget->expandItem(parent);
+ testWidget->scrollToItem(child);
+
+ QVERIFY(testWidget->visualItemRect(parent).isValid()
+ && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(parent)));
+ QVERIFY(testWidget->visualItemRect(child).isValid()
+ && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(child)));
+
+ QVERIFY(!testWidget->isItemHidden(parent));
+ QVERIFY(!testWidget->isItemHidden(child));
+
+ testWidget->setItemHidden(parent, true);
+
+ QVERIFY(!(testWidget->visualItemRect(parent).isValid()
+ && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(parent))));
+ QVERIFY(!(testWidget->visualItemRect(child).isValid()
+ && testWidget->viewport()->rect().intersects(testWidget->visualItemRect(child))));
+
+ QVERIFY(testWidget->isItemHidden(parent));
+ QVERIFY(!testWidget->isItemHidden(child));
+
+ // From task 78670 (This caused an core dump)
+ // Check if we can set an item visible if it already is visible.
+ testWidget->setItemHidden(parent, false);
+ testWidget->setItemHidden(parent, false);
+ QVERIFY(!testWidget->isItemHidden(parent));
+
+
+ // hide, hide and then unhide.
+ testWidget->setItemHidden(parent, true);
+ testWidget->setItemHidden(parent, true);
+ testWidget->setItemHidden(parent, false);
+ QVERIFY(!testWidget->isItemHidden(parent));
+
+
+}
+
+
+void tst_QTreeWidget::setItemHidden2()
+{
+ // From Task 78587
+ QStringList hl;
+ hl << "ID" << "Desc";
+ testWidget->setColumnCount(hl.count());
+ testWidget->setHeaderLabels(hl);
+ testWidget->setSortingEnabled(true);
+
+ QTreeWidgetItem *top = new QTreeWidgetItem(testWidget);
+ QTreeWidgetItem *leaf = 0;
+ top->setText(0, "ItemList");
+ for (int i = 1; i <= 4; i++) {
+ leaf = new QTreeWidgetItem(top);
+ leaf->setText(0, QString().sprintf("%d", i));
+ leaf->setText(1, QString().sprintf("Item %d", i));
+ }
+
+ if (testWidget->topLevelItemCount() > 0) {
+ top = testWidget->topLevelItem(0);
+ testWidget->setItemExpanded(top, true);
+ }
+
+ if (testWidget->topLevelItemCount() > 0) {
+ top = testWidget->topLevelItem(0);
+ for (int i = 0; i < top->childCount(); i++) {
+ leaf = top->child(i);
+ if (leaf->text(0).toInt() % 2 == 0) {
+ if (!testWidget->isItemHidden(leaf)) {
+ testWidget->setItemHidden(leaf, true);
+ }
+ }
+ }
+ }
+}
+
+
+void tst_QTreeWidget::selectedItems_data()
+{
+ QTest::addColumn<int>("topLevel");
+ QTest::addColumn<int>("children");
+ QTest::addColumn<bool>("closeTopLevel");
+ QTest::addColumn<ListIntList>("selectedItems");
+ QTest::addColumn<ListIntList>("hiddenItems");
+ QTest::addColumn<ListIntList>("expectedItems");
+
+ ListIntList selectedItems;
+ ListIntList hiddenItems;
+ ListIntList expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems
+ << (IntList()
+ << 0);
+ expectedItems
+ << (IntList() << 0);
+ QTest::newRow("2 top with 2 children, closed, top0 selected, no hidden")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems
+ << (IntList()
+ << 0 << 0);
+ expectedItems
+ << (IntList() << 0 << 0);
+ QTest::newRow("2 top with 2 children, closed, top0child0 selected, no hidden")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems
+ << (IntList()
+ << 0 << 0);
+ expectedItems
+ << (IntList()
+ << 0 << 0);
+ QTest::newRow("2 top with 2 children, open, top0child0 selected, no hidden")
+ << 2 << 2 << false << selectedItems << hiddenItems << expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems << (IntList() << 0);
+ hiddenItems << (IntList() << 0);
+ QTest::newRow("2 top with 2 children, closed, top0 selected, top0 hidden")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems << (IntList() << 0 << 0);
+ hiddenItems << (IntList() << 0);
+ expectedItems << (IntList() << 0 << 0);
+ QTest::newRow("2 top with 2 children, closed, top0child0 selected, top0 hidden")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems
+ << (IntList() << 0)
+ << (IntList() << 0 << 0)
+ << (IntList() << 0 << 1)
+ << (IntList() << 1)
+ << (IntList() << 1 << 0)
+ << (IntList() << 1 << 1);
+ expectedItems
+ << (IntList() << 0)
+ << (IntList() << 0 << 0)
+ << (IntList() << 0 << 1)
+ << (IntList() << 1)
+ << (IntList() << 1 << 0)
+ << (IntList() << 1 << 1);
+ QTest::newRow("2 top with 2 children, closed, all selected, no hidden")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems
+ << (IntList() << 0)
+ << (IntList() << 0 << 0)
+ << (IntList() << 0 << 1)
+ << (IntList() << 1)
+ << (IntList() << 1 << 0)
+ << (IntList() << 1 << 1);
+ hiddenItems
+ << (IntList() << 0);
+ expectedItems
+ //<< (IntList() << 0)
+ << (IntList() << 0 << 0)
+ << (IntList() << 0 << 1)
+ << (IntList() << 1)
+ << (IntList() << 1 << 0)
+ << (IntList() << 1 << 1);
+ QTest::newRow("2 top with 2 children, closed, all selected, top0 hidden")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+ selectedItems.clear(); hiddenItems.clear(); expectedItems.clear();
+ selectedItems
+ << (IntList() << 0)
+ << (IntList() << 0 << 0)
+ << (IntList() << 0 << 1)
+ << (IntList() << 1)
+ << (IntList() << 1 << 0)
+ << (IntList() << 1 << 1);
+ hiddenItems
+ << (IntList() << 0 << 1)
+ << (IntList() << 1);
+ expectedItems
+ << (IntList() << 0)
+ << (IntList() << 0 << 0)
+ //<< (IntList() << 0 << 1)
+ //<< (IntList() << 1)
+ << (IntList() << 1 << 0)
+ << (IntList() << 1 << 1);
+
+ QTest::newRow("2 top with 2 children, closed, all selected, top0child1 and top1")
+ << 2 << 2 << true << selectedItems << hiddenItems << expectedItems;
+
+}
+
+void tst_QTreeWidget::selectedItems()
+{
+ QFETCH(int, topLevel);
+ QFETCH(int, children);
+ QFETCH(bool, closeTopLevel);
+ QFETCH(ListIntList, selectedItems);
+ QFETCH(ListIntList, hiddenItems);
+ QFETCH(ListIntList, expectedItems);
+
+ // create items
+ for (int t=0; t<topLevel; ++t) {
+ QTreeWidgetItem *top = new QTreeWidgetItem(testWidget);
+ top->setText(0, QString("top%1").arg(t));
+ for (int c=0; c<children; ++c) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(top);
+ child->setText(0, QString("top%1child%2").arg(t).arg(c));
+ }
+ }
+
+ // set selected
+ foreach (IntList itemPath, selectedItems) {
+ QTreeWidgetItem *item = 0;
+ foreach(int index, itemPath) {
+ if (!item)
+ item = testWidget->topLevelItem(index);
+ else
+ item = item->child(index);
+ }
+ testWidget->setItemSelected(item, true);
+ }
+
+ // hide rows
+ foreach (IntList itemPath, hiddenItems) {
+ QTreeWidgetItem *item = 0;
+ foreach(int index, itemPath) {
+ if (!item)
+ item = testWidget->topLevelItem(index);
+ else
+ item = item->child(index);
+ }
+ testWidget->setItemHidden(item, true);
+ }
+
+ // open/close toplevel
+ for (int i=0; i<testWidget->topLevelItemCount(); ++i) {
+ if (closeTopLevel)
+ testWidget->collapseItem(testWidget->topLevelItem(i));
+ else
+ testWidget->expandItem(testWidget->topLevelItem(i));
+ }
+
+ // check selectedItems
+ QList<QTreeWidgetItem*> sel = testWidget->selectedItems();
+ QCOMPARE(sel.count(), expectedItems.count());
+ foreach (IntList itemPath, expectedItems) {
+ QTreeWidgetItem *item = 0;
+ foreach(int index, itemPath) {
+ if (!item)
+ item = testWidget->topLevelItem(index);
+ else
+ item = item->child(index);
+ }
+ if (item)
+ QVERIFY(sel.contains(item));
+ }
+
+ // compare isSelected
+ for (int t=0; t<testWidget->topLevelItemCount(); ++t) {
+ QTreeWidgetItem *top = testWidget->topLevelItem(t);
+ if (testWidget->isItemSelected(top) && !testWidget->isItemHidden(top))
+ QVERIFY(sel.contains(top));
+ for (int c=0; c<top->childCount(); ++c) {
+ QTreeWidgetItem *child = top->child(c);
+ if (testWidget->isItemSelected(child) && !testWidget->isItemHidden(child))
+ QVERIFY(sel.contains(child));
+ }
+ }
+
+ // Possible to select null without crashing?
+ testWidget->setItemSelected(0, true);
+ QVERIFY(!testWidget->isItemSelected(0));
+
+ // unselect
+ foreach (IntList itemPath, selectedItems) {
+ QTreeWidgetItem *item = 0;
+ foreach(int index, itemPath) {
+ if (!item)
+ item = testWidget->topLevelItem(index);
+ else
+ item = item->child(index);
+ }
+ testWidget->setItemSelected(item, false);
+ }
+ QCOMPARE(testWidget->selectedItems().count(), 0);
+}
+
+void tst_QTreeWidget::itemAssignment()
+{
+ // create item with children and parent but not insert in the view
+ QTreeWidgetItem grandParent;
+ QTreeWidgetItem *parent = new QTreeWidgetItem(&grandParent);
+ parent->setText(0, "foo");
+ parent->setText(1, "bar");
+ for (int i=0; i<5; ++i) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(parent);
+ child->setText(0, "bingo");
+ child->setText(1, "bango");
+ }
+ QCOMPARE(parent->parent(), &grandParent);
+ QVERIFY(!parent->treeWidget());
+ QCOMPARE(parent->columnCount(), 2);
+ QCOMPARE(parent->text(0), QString("foo"));
+ QCOMPARE(parent->childCount(), 5);
+ QCOMPARE(parent->child(0)->parent(), parent);
+
+ // create item which is inserted in the widget
+ QTreeWidgetItem item(testWidget);
+ item.setText(0, "baz");
+ QVERIFY(!item.parent());
+ QCOMPARE(item.treeWidget(), static_cast<QTreeWidget *>(testWidget));
+ QCOMPARE(item.columnCount(), 1);
+ QCOMPARE(item.text(0), QString("baz"));
+ QCOMPARE(item.childCount(), 0);
+
+ // assign and test
+ *parent = item;
+ QCOMPARE(parent->parent(), &grandParent);
+ QVERIFY(!parent->treeWidget());
+ QCOMPARE(parent->columnCount(), 1);
+ QCOMPARE(parent->text(0), QString("baz"));
+ QCOMPARE(parent->childCount(), 5);
+ QCOMPARE(parent->child(0)->parent(), parent);
+}
+
+void tst_QTreeWidget::clone_data()
+{
+ QTest::addColumn<int>("column");
+ QTest::addColumn<int>("topLevelIndex");
+ QTest::addColumn<int>("childIndex");
+ QTest::addColumn<QStringList>("topLevelText");
+ QTest::addColumn<QStringList>("childText");
+ QTest::addColumn<bool>("cloneChild");
+
+ QTest::newRow("clone parent with child") << 0 << 0 << 0
+ << (QStringList() << "some text")
+ << (QStringList() << "more text")
+ << false;
+
+ QTest::newRow("clone child") << 0 << 0 << 0
+ << (QStringList() << "some text")
+ << (QStringList() << "more text")
+ << true;
+}
+
+void tst_QTreeWidget::clone()
+{
+ QFETCH(int, column);
+ QFETCH(int, topLevelIndex);
+ QFETCH(int, childIndex);
+ QFETCH(QStringList, topLevelText);
+ QFETCH(QStringList, childText);
+ QFETCH(bool, cloneChild);
+
+ for (int i = 0; i < topLevelText.count(); ++i) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(testWidget);
+ item->setText(column, topLevelText.at(i));
+ for (int j = 0; j < childText.count(); ++j) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(item);
+ child->setText(column, childText.at(j));
+ }
+ }
+
+ QTreeWidgetItem *original = testWidget->topLevelItem(topLevelIndex);
+ QTreeWidgetItem *copy = original->clone();
+ QCOMPARE(copy->text(column), original->text(column));
+ QCOMPARE(copy->childCount(), original->childCount());
+ QVERIFY(!copy->parent());
+ QVERIFY(!copy->treeWidget());
+
+ QTreeWidgetItem *originalChild = original->child(childIndex);
+ QTreeWidgetItem *copiedChild = cloneChild ? originalChild->clone() : copy->child(childIndex);
+ QVERIFY(copiedChild != originalChild);
+ QCOMPARE(copiedChild->text(column), originalChild->text(column));
+ QCOMPARE(copiedChild->childCount(), originalChild->childCount());
+ QCOMPARE(copiedChild->parent(), cloneChild ? 0 : copy);
+ QVERIFY(!copiedChild->treeWidget());
+ if (cloneChild)
+ delete copiedChild;
+ delete copy;
+}
+
+void tst_QTreeWidget::expand_data()
+{
+ QTest::addColumn<int>("topLevelIndex");
+ QTest::addColumn<int>("topLevelCount");
+ QTest::addColumn<int>("childIndex");
+ QTest::addColumn<int>("childCount");
+
+ QTest::newRow("the only test data for now") << 0 << 1 << 0 << 1;
+}
+
+void tst_QTreeWidget::expand()
+{
+ QFETCH(int, topLevelIndex);
+ QFETCH(int, topLevelCount);
+ QFETCH(int, childIndex);
+ QFETCH(int, childCount);
+
+ for (int i = 0; i < topLevelCount; ++i) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(testWidget);
+ for (int j = 0; j < childCount; ++j)
+ new QTreeWidgetItem(item);
+ }
+
+ QTreeWidgetItem *topLevelItem = testWidget->topLevelItem(topLevelIndex);
+ QTreeWidgetItem *childItem = topLevelItem->child(childIndex);
+
+ QVERIFY(!testWidget->isItemExpanded(topLevelItem));
+ testWidget->setItemExpanded(topLevelItem, true);
+ QVERIFY(testWidget->isItemExpanded(topLevelItem));
+
+ QVERIFY(!testWidget->isItemExpanded(childItem));
+ testWidget->setItemExpanded(childItem, true);
+ QVERIFY(testWidget->isItemExpanded(childItem));
+
+ QVERIFY(testWidget->isItemExpanded(topLevelItem));
+ testWidget->setItemExpanded(topLevelItem, false);
+ QVERIFY(!testWidget->isItemExpanded(topLevelItem));
+
+ QVERIFY(testWidget->isItemExpanded(childItem));
+ testWidget->setItemExpanded(childItem, false);
+ QVERIFY(!testWidget->isItemExpanded(childItem));
+}
+
+void tst_QTreeWidget::checkState_data()
+{
+}
+
+void tst_QTreeWidget::checkState()
+{
+ QTreeWidgetItem *item = new QTreeWidgetItem(testWidget);
+ item->setCheckState(0, Qt::Unchecked);
+ QTreeWidgetItem *firstChild = new QTreeWidgetItem(item);
+ firstChild->setCheckState(0, Qt::Unchecked);
+ QTreeWidgetItem *seccondChild = new QTreeWidgetItem(item);
+ seccondChild->setCheckState(0, Qt::Unchecked);
+
+ QCOMPARE(item->checkState(0), Qt::Unchecked);
+ QCOMPARE(firstChild->checkState(0), Qt::Unchecked);
+ QCOMPARE(seccondChild->checkState(0), Qt::Unchecked);
+
+ firstChild->setCheckState(0, Qt::Checked);
+ QCOMPARE(item->checkState(0), Qt::Unchecked);
+ QCOMPARE(firstChild->checkState(0), Qt::Checked);
+ QCOMPARE(seccondChild->checkState(0), Qt::Unchecked);
+
+ item->setFlags(item->flags()|Qt::ItemIsTristate);
+ QCOMPARE(item->checkState(0), Qt::PartiallyChecked);
+ QCOMPARE(firstChild->checkState(0), Qt::Checked);
+ QCOMPARE(seccondChild->checkState(0), Qt::Unchecked);
+
+ seccondChild->setCheckState(0, Qt::Checked);
+ QCOMPARE(item->checkState(0), Qt::Checked);
+ QCOMPARE(firstChild->checkState(0), Qt::Checked);
+ QCOMPARE(seccondChild->checkState(0), Qt::Checked);
+
+ firstChild->setCheckState(0, Qt::Unchecked);
+ seccondChild->setCheckState(0, Qt::Unchecked);
+ QCOMPARE(item->checkState(0), Qt::Unchecked);
+ QCOMPARE(firstChild->checkState(0), Qt::Unchecked);
+ QCOMPARE(seccondChild->checkState(0), Qt::Unchecked);
+}
+
+void tst_QTreeWidget::findItems_data()
+{
+ QTest::addColumn<int>("column");
+ QTest::addColumn<QStringList>("topLevelText");
+ QTest::addColumn<QStringList>("childText");
+ QTest::addColumn<QString>("pattern");
+ QTest::addColumn<int>("resultCount");
+ QTest::addColumn<QStringList>("resultText");
+
+ QTest::newRow("find in toplevel")
+ << 0
+ << (QStringList() << "This is a text" << "This is another" << "This is the one")
+ << (QStringList() << "A child" << "This is not the one" << "And yet another child")
+ << "This is the one"
+ << 1
+ << (QStringList() << "This is the one");
+
+ QTest::newRow("find child")
+ << 0
+ << (QStringList() << "This is a text" << "This is another" << "This is the one")
+ << (QStringList() << "A child" << "This is not the one" << "And yet another child")
+ << "A child"
+ << 3 // once for each branch
+ << (QStringList() << "A child");
+
+}
+
+void tst_QTreeWidget::findItems()
+{
+ QFETCH(int, column);
+ QFETCH(QStringList, topLevelText);
+ QFETCH(QStringList, childText);
+ QFETCH(QString, pattern);
+ QFETCH(int, resultCount);
+ QFETCH(QStringList, resultText);
+
+ for (int i = 0; i < topLevelText.count(); ++i) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(testWidget);
+ item->setText(column, topLevelText.at(i));
+ for (int j = 0; j < childText.count(); ++j) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(item);
+ child->setText(column, childText.at(j));
+ }
+ }
+
+ QList<QTreeWidgetItem*> result = testWidget->findItems(pattern,
+ Qt::MatchExactly|Qt::MatchRecursive);
+ QCOMPARE(result.count(), resultCount);
+
+ for (int k = 0; k < result.count() && k < resultText.count(); ++k)
+ QCOMPARE(result.at(k)->text(column), resultText.at(k));
+}
+
+void tst_QTreeWidget::findItemsInColumn()
+{
+ // Create 5 root items.
+ for (int i = 0; i < 5; i++)
+ new QTreeWidgetItem(testWidget, QStringList() << QString::number(i));
+
+ // Create a child with two columns for each root item.
+ for (int i = 0; i < 5; i++) {
+ QTreeWidgetItem * const parent = testWidget->topLevelItem(i);
+ new QTreeWidgetItem(parent, QStringList() << QString::number(i * 10) << QString::number(i * 100));
+ }
+
+ // Recursively search column one for 400.
+ QList<QTreeWidgetItem*> items = testWidget->findItems("400", Qt::MatchExactly|Qt::MatchRecursive, 1);
+ QCOMPARE(items.count(), 1);
+}
+
+void tst_QTreeWidget::sortItems_data()
+{
+ QTest::addColumn<int>("column");
+ QTest::addColumn<int>("order");
+ QTest::addColumn<QStringList>("topLevelText");
+ QTest::addColumn<QStringList>("childText");
+ QTest::addColumn<QStringList>("topLevelResult");
+ QTest::addColumn<QStringList>("childResult");
+ QTest::addColumn<IntList>("expectedTopRows");
+ QTest::addColumn<IntList>("expectedChildRows");
+
+ QTest::newRow("ascending order")
+ << 0
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "c" << "d" << "a" << "b")
+ << (QStringList() << "e" << "h" << "g" << "f")
+ << (QStringList() << "a" << "b" << "c" << "d")
+ << (QStringList() << "e" << "f" << "g" << "h")
+ << (IntList() << 2 << 3 << 0 << 1)
+ << (IntList() << 0 << 3 << 2 << 1);
+
+ QTest::newRow("descending order")
+ << 0
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QStringList() << "c" << "d" << "a" << "b")
+ << (QStringList() << "e" << "h" << "g" << "f")
+ << (QStringList() << "d" << "c" << "b" << "a")
+ << (QStringList() << "h" << "g" << "f" << "e")
+ << (IntList() << 1 << 0 << 3 << 2)
+ << (IntList() << 3 << 0 << 1 << 2);
+}
+
+void tst_QTreeWidget::sortItems()
+{
+ QFETCH(int, column);
+ QFETCH(int, order);
+ QFETCH(QStringList, topLevelText);
+ QFETCH(QStringList, childText);
+ QFETCH(QStringList, topLevelResult);
+ QFETCH(QStringList, childResult);
+ QFETCH(IntList, expectedTopRows);
+ QFETCH(IntList, expectedChildRows);
+ testWidget->setSortingEnabled(false);
+
+ for (int i = 0; i < topLevelText.count(); ++i) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(testWidget);
+ item->setText(column, topLevelText.at(i));
+ for (int j = 0; j < childText.count(); ++j) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(item);
+ child->setText(column, childText.at(j));
+ }
+ }
+
+ QAbstractItemModel *model = testWidget->model();
+ QList<QPersistentModelIndex> tops;
+ for (int r = 0; r < model->rowCount(QModelIndex()); ++r) {
+ QPersistentModelIndex p = model->index(r, 0, QModelIndex());
+ tops << p;
+ }
+ QList<QPersistentModelIndex> children;
+ for (int s = 0; s < model->rowCount(tops.first()); ++s) {
+ QPersistentModelIndex c = model->index(s, 0, tops.first());
+ children << c;
+ }
+
+ testWidget->sortItems(column, static_cast<Qt::SortOrder>(order));
+ QCOMPARE(testWidget->sortColumn(), column);
+
+ for (int k = 0; k < topLevelResult.count(); ++k) {
+ QTreeWidgetItem *item = testWidget->topLevelItem(k);
+ QCOMPARE(item->text(column), topLevelResult.at(k));
+ for (int l = 0; l < childResult.count(); ++l)
+ QCOMPARE(item->child(l)->text(column), childResult.at(l));
+ }
+
+ for (int m = 0; m < tops.count(); ++m)
+ QCOMPARE(tops.at(m).row(), expectedTopRows.at(m));
+ for (int n = 0; n < children.count(); ++n)
+ QCOMPARE(children.at(n).row(), expectedChildRows.at(n));
+}
+
+void tst_QTreeWidget::deleteItems_data()
+{
+ QTest::addColumn<int>("topLevelCount");
+ QTest::addColumn<int>("childCount");
+ QTest::addColumn<int>("grandChildCount");
+
+ QTest::addColumn<int>("deleteTopLevelCount");
+ QTest::addColumn<int>("deleteChildCount");
+ QTest::addColumn<int>("deleteGrandChildCount");
+
+ QTest::addColumn<int>("expectedTopLevelCount");
+ QTest::addColumn<int>("expectedChildCount");
+ QTest::addColumn<int>("expectedGrandChildCount");
+
+ QTest::addColumn<int>("persistentRow");
+ QTest::addColumn<int>("persistentColumn");
+ QTest::addColumn<bool>("persistentIsValid");
+
+ QTest::newRow("start with 10, delete 1")
+ << 10 << 10 << 10
+ << 1 << 1 << 1
+ << 9 << 9 << 9
+ << 0 << 0 << false;
+ QTest::newRow("start with 10, delete 5")
+ << 10 << 10 << 10
+ << 5 << 5 << 5
+ << 5 << 5 << 5
+ << 0 << 0 << false;
+ QTest::newRow("mixed")
+ << 10 << 13 << 7
+ << 3 << 7 << 4
+ << 7 << 6 << 3
+ << 0 << 0 << false;
+ QTest::newRow("all")
+ << 10 << 10 << 10
+ << 10 << 10 << 10
+ << 0 << 0 << 0
+ << 0 << 0 << false;
+}
+
+void tst_QTreeWidget::deleteItems()
+{
+ QFETCH(int, topLevelCount);
+ QFETCH(int, childCount);
+ QFETCH(int, grandChildCount);
+
+ QFETCH(int, deleteTopLevelCount);
+ QFETCH(int, deleteChildCount);
+ QFETCH(int, deleteGrandChildCount);
+
+ QFETCH(int, expectedTopLevelCount);
+ QFETCH(int, expectedChildCount);
+ QFETCH(int, expectedGrandChildCount);
+
+ QFETCH(int, persistentRow);
+ QFETCH(int, persistentColumn);
+ QFETCH(bool, persistentIsValid);
+
+ for (int i = 0; i < topLevelCount; ++i) {
+ QTreeWidgetItem *top = new QTreeWidgetItem(testWidget);
+ for (int j = 0; j < childCount; ++j) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(top);
+ for (int k = 0; k < grandChildCount; ++k) {
+ new QTreeWidgetItem(child);
+ }
+ }
+ }
+
+ QPersistentModelIndex persistent = testWidget->model()->index(persistentRow,
+ persistentColumn);
+ QVERIFY(persistent.isValid());
+
+ QTreeWidgetItem *top = testWidget->topLevelItem(0);
+ QTreeWidgetItem *child = top->child(0);
+
+ for (int n = 0; n < deleteGrandChildCount; ++n)
+ delete child->child(0);
+ QCOMPARE(child->childCount(), expectedGrandChildCount);
+
+ for (int m = 0; m < deleteChildCount; ++m)
+ delete top->child(0);
+ QCOMPARE(top->childCount(), expectedChildCount);
+
+ for (int l = 0; l < deleteTopLevelCount; ++l)
+ delete testWidget->topLevelItem(0);
+ QCOMPARE(testWidget->topLevelItemCount(), expectedTopLevelCount);
+
+ QCOMPARE(persistent.isValid(), persistentIsValid);
+}
+
+
+void tst_QTreeWidget::itemAboveOrBelow()
+{
+ QTreeWidget tw;
+ tw.setColumnCount(1);
+ QTreeWidgetItem *twi = new QTreeWidgetItem(&tw, QStringList() << "Test");
+ QTreeWidgetItem *twi2 = new QTreeWidgetItem(&tw, QStringList() << "Test 2");
+ QTreeWidgetItem *twi3 = new QTreeWidgetItem(&tw, QStringList() << "Test 3");
+ tw.show();
+ QCOMPARE(tw.itemAbove(twi2), twi);
+ QCOMPARE(tw.itemBelow(twi2), twi3);
+}
+
+void tst_QTreeWidget::itemStreaming_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("toolTip");
+ QTest::addColumn<int>("column");
+
+ QTest::newRow("Data") << "item text" << "tool tip text" << 0;
+}
+
+void tst_QTreeWidget::itemStreaming()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, toolTip);
+ QFETCH(int, column);
+
+ QTreeWidgetItem item(testWidget);
+ QCOMPARE(item.text(column), QString());
+ QCOMPARE(item.toolTip(column), QString());
+
+ item.setText(column, text);
+ item.setToolTip(column, toolTip);
+ QCOMPARE(item.text(column), text);
+ QCOMPARE(item.toolTip(column), toolTip);
+
+ QByteArray buffer;
+ QDataStream out(&buffer, QIODevice::WriteOnly);
+ out << item;
+
+ QTreeWidgetItem item2(testWidget);
+ QCOMPARE(item2.text(column), QString());
+ QCOMPARE(item2.toolTip(column), QString());
+
+ QVERIFY(!buffer.isEmpty());
+
+ QDataStream in(&buffer, QIODevice::ReadOnly);
+ in >> item2;
+ QCOMPARE(item2.text(column), text);
+ QCOMPARE(item2.toolTip(column), toolTip);
+}
+
+void tst_QTreeWidget::insertTopLevelItems_data()
+{
+ QTest::addColumn<QStringList>("initialText");
+ QTest::addColumn<QStringList>("insertText");
+ QTest::addColumn<int>("insertTopLevelIndex");
+ QTest::addColumn<int>("expectedTopLevelIndex");
+ QTest::addColumn<int>("insertChildIndex");
+ QTest::addColumn<int>("expectedChildIndex");
+
+ QStringList initial = (QStringList() << "foo" << "bar");
+ QStringList insert = (QStringList() << "baz");
+
+ QTest::newRow("Insert at count") << initial << insert
+ << initial.count() << initial.count()
+ << initial.count() << initial.count();
+ QTest::newRow("Insert in the middle") << initial << insert
+ << (initial.count() / 2) << (initial.count() / 2)
+ << (initial.count() / 2) << (initial.count() / 2);
+ QTest::newRow("Insert less than 0") << initial << insert
+ << -1 << -1
+ << -1 << -1;
+ QTest::newRow("Insert beyond count") << initial << insert
+ << initial.count() + 1 << -1
+ << initial.count() + 1 << -1;
+}
+
+void tst_QTreeWidget::insertTopLevelItems()
+{
+ QFETCH(QStringList, initialText);
+ QFETCH(QStringList, insertText);
+ QFETCH(int, insertTopLevelIndex);
+ QFETCH(int, expectedTopLevelIndex);
+ QFETCH(int, insertChildIndex);
+ QFETCH(int, expectedChildIndex);
+ testWidget->setSortingEnabled(false);
+
+ { // insert the initial items
+ QCOMPARE(testWidget->topLevelItemCount(), 0);
+ for (int i = 0; i < initialText.count(); ++i) {
+ QTreeWidgetItem *top = new QTreeWidgetItem(QStringList(initialText.at(i)));
+ testWidget->addTopLevelItem(top);
+ QCOMPARE(testWidget->indexOfTopLevelItem(top), i);
+ }
+ QCOMPARE(testWidget->topLevelItemCount(), initialText.count());
+ }
+
+ { // test adding children
+ QTreeWidgetItem *topLevel = testWidget->topLevelItem(0);
+ for (int i = 0; i < initialText.count(); ++i)
+ topLevel->addChild(new QTreeWidgetItem(QStringList(initialText.at(i))));
+ QCOMPARE(topLevel->childCount(), initialText.count());
+ }
+
+ { // test adding more top level items
+ QTreeWidgetItem *topsy = new QTreeWidgetItem(QStringList(insertText.at(0)));
+ testWidget->insertTopLevelItem(insertTopLevelIndex, topsy);
+ if (expectedTopLevelIndex == -1) {
+ QCOMPARE(testWidget->topLevelItemCount(), initialText.count());
+ delete topsy;
+ } else {
+ QTreeWidgetItem *item = testWidget->topLevelItem(expectedTopLevelIndex);
+ QVERIFY(item != 0);
+ QCOMPARE(item->text(0), insertText.at(0));
+ QCOMPARE(testWidget->indexOfTopLevelItem(item), expectedTopLevelIndex);
+ }
+ }
+
+ { // test adding more children
+ QTreeWidgetItem *topLevel = testWidget->topLevelItem(0);
+ QVERIFY(topLevel != 0);
+ QTreeWidgetItem *child = new QTreeWidgetItem(QStringList(insertText.at(0)));
+ topLevel->insertChild(insertChildIndex, child);
+ if (expectedChildIndex == -1) {
+ QCOMPARE(topLevel->childCount(), initialText.count());
+ delete child;
+ } else {
+ QTreeWidgetItem *item = topLevel->child(expectedChildIndex);
+ QVERIFY(item != 0);
+ QCOMPARE(item->text(0), insertText.at(0));
+ }
+ }
+}
+
+static void fillTreeWidget(QTreeWidgetItem *parent, int rows)
+{
+ const int columns = parent->treeWidget()->columnCount();
+ for (int r = 0; r < rows; ++r) {
+ QTreeWidgetItem *w = new QTreeWidgetItem(parent);
+ for ( int c = 0; c < columns; ++c ) {
+ QString s = QString("[r:%1,c:%2]").arg(r).arg(c);
+ w->setText(c, s);
+ }
+ fillTreeWidget(w, rows - r - 1);
+ }
+}
+
+static void fillTreeWidget(QTreeWidget *tree, int rows)
+{
+ for (int r = 0; r < rows; ++r) {
+ QTreeWidgetItem *w = new QTreeWidgetItem();
+ for ( int c = 0; c < tree->columnCount(); ++c ) {
+ QString s = QString("[r:%1,c:%2]").arg(r).arg(c);
+ w->setText(c, s);
+ }
+ tree->insertTopLevelItem(r, w);
+ fillTreeWidget(w, rows - r - 1);
+ }
+}
+
+void tst_QTreeWidget::keyboardNavigation()
+{
+ int rows = 8;
+
+ fillTreeWidget(testWidget, rows);
+
+ QVector<Qt::Key> keymoves;
+ keymoves << Qt::Key_Down << Qt::Key_Right << Qt::Key_Left
+ << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down << Qt::Key_Down
+ << Qt::Key_Right
+ << Qt::Key_Up << Qt::Key_Left << Qt::Key_Left
+ << Qt::Key_Up << Qt::Key_Down << Qt::Key_Up << Qt::Key_Up
+ << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up
+ << Qt::Key_Down << Qt::Key_Right << Qt::Key_Down << Qt::Key_Down
+ << Qt::Key_Down << Qt::Key_Right << Qt::Key_Down << Qt::Key_Down
+ << Qt::Key_Left << Qt::Key_Left << Qt::Key_Up << Qt::Key_Down
+ << Qt::Key_Up << Qt::Key_Up << Qt::Key_Up << Qt::Key_Left
+ << Qt::Key_Down << Qt::Key_Right << Qt::Key_Right << Qt::Key_Right
+ << Qt::Key_Left << Qt::Key_Left << Qt::Key_Right << Qt::Key_Left;
+
+ int row = 0;
+ QTreeWidgetItem *item = testWidget->topLevelItem(0);
+ testWidget->setCurrentItem(item);
+ QCOMPARE(testWidget->currentItem(), item);
+ QApplication::instance()->processEvents();
+
+ QScrollBar *scrollBar = testWidget->horizontalScrollBar();
+ bool checkScroll = false;
+ for (int i = 0; i < keymoves.size(); ++i) {
+ Qt::Key key = keymoves.at(i);
+ int valueBeforeClick = scrollBar->value();
+ if (valueBeforeClick >= scrollBar->singleStep())
+ checkScroll = true;
+ else
+ checkScroll = false;
+ QTest::keyClick(testWidget, key);
+ QApplication::instance()->processEvents();
+
+ switch (key) {
+ case Qt::Key_Up:
+ if (row > 0) {
+ if (item->parent())
+ item = item->parent()->child(row - 1);
+ else
+ item = testWidget->topLevelItem(row - 1);
+ row -= 1;
+ } else if (item->parent()) {
+ item = item->parent();
+ row = item->parent() ? item->parent()->indexOfChild(item) : testWidget->indexOfTopLevelItem(item);
+ }
+ break;
+ case Qt::Key_Down:
+ if (testWidget->isItemExpanded(item)) {
+ row = 0;
+ item = item->child(row);
+ } else {
+ row = qMin(rows - 1, row + 1);
+ if (item->parent())
+ item = item->parent()->child(row);
+ else
+ item = testWidget->topLevelItem(row);
+ }
+ break;
+ case Qt::Key_Left:
+ if (checkScroll) {
+ QVERIFY(testWidget->isItemExpanded(item));
+ QCOMPARE(scrollBar->value(), valueBeforeClick - scrollBar->singleStep());
+ }
+ // windows style right will walk to the parent
+ if (testWidget->currentItem() != item) {
+ QCOMPARE(testWidget->currentItem(), item->parent());
+ item = testWidget->currentItem();
+ row = item->parent() ? item->parent()->indexOfChild(item) : testWidget->indexOfTopLevelItem(item);;
+ }
+ break;
+ case Qt::Key_Right:
+ if (checkScroll)
+ QCOMPARE(scrollBar->value(), valueBeforeClick + scrollBar->singleStep());
+ // windows style right will walk to the first child
+ if (testWidget->currentItem() != item) {
+ QCOMPARE(testWidget->currentItem()->parent(), item);
+ row = item->indexOfChild(testWidget->currentItem());
+ item = testWidget->currentItem();
+ QCOMPARE(row, 0);
+ }
+ break;
+ default:
+ QVERIFY(false);
+ }
+
+ QTreeWidgetItem *current = testWidget->currentItem();
+ QCOMPARE(current->text(0), QString("[r:%1,c:0]").arg(row));
+ if (current->parent())
+ QCOMPARE(current->parent()->indexOfChild(current), row);
+ else
+ QCOMPARE(testWidget->indexOfTopLevelItem(current), row);
+ }
+}
+
+void tst_QTreeWidget::scrollToItem()
+{
+ // Check if all parent nodes of the item found are expanded.
+ // Reported in task #78761
+ QTreeWidgetItem *bar;
+ QTreeWidgetItem *search;
+ for (int i=0; i<2; ++i) {
+ bar = new QTreeWidgetItem(testWidget);
+ bar->setText(0, QString::number(i));
+
+ for (int j=0; j<2; ++j) {
+ QTreeWidgetItem *foo = new QTreeWidgetItem(bar);
+ foo->setText(0, bar->text(0) + QString::number(j));
+
+ for (int k=0; k<2; ++k) {
+ QTreeWidgetItem *yo = new QTreeWidgetItem(foo);
+ yo->setText(0, foo->text(0) + QString::number(k));
+ search = yo;
+ }
+ }
+ }
+
+ testWidget->setHeaderLabels(QStringList() << "foo");
+ testWidget->scrollToItem(search);
+ QVERIFY(search->text(0) == "111");
+
+ bar = search->parent();
+ QVERIFY(testWidget->isItemExpanded(bar));
+ bar = bar->parent();
+ QVERIFY(testWidget->isItemExpanded(bar));
+}
+
+// From task #85413
+void tst_QTreeWidget::setSortingEnabled()
+{
+ QStringList hl;
+ hl << "ID";
+ testWidget->setColumnCount(hl.count());
+ testWidget->setHeaderLabels(hl);
+
+ QTreeWidgetItem *item1 = new QTreeWidgetItem(testWidget);
+ QTreeWidgetItem *item2 = new QTreeWidgetItem(testWidget);
+
+ testWidget->setSortingEnabled(true);
+ QCOMPARE(testWidget->isSortingEnabled(), true);
+ QCOMPARE(testWidget->isSortingEnabled(), testWidget->header()->isSortIndicatorShown());
+ QCOMPARE(testWidget->topLevelItem(0), item1);
+ QCOMPARE(testWidget->topLevelItem(1), item2);
+
+ // Make sure we do it twice
+ testWidget->setSortingEnabled(true);
+ QCOMPARE(testWidget->isSortingEnabled(), true);
+ QCOMPARE(testWidget->isSortingEnabled(), testWidget->header()->isSortIndicatorShown());
+
+ testWidget->setSortingEnabled(false);
+ QCOMPARE(testWidget->isSortingEnabled(), false);
+ QCOMPARE(testWidget->isSortingEnabled(), testWidget->header()->isSortIndicatorShown());
+
+ testWidget->setSortingEnabled(false);
+ QCOMPARE(testWidget->isSortingEnabled(), false);
+ QCOMPARE(testWidget->isSortingEnabled(), testWidget->header()->isSortIndicatorShown());
+
+ // And back again so that we make sure that we test the transition from false to true
+ testWidget->setSortingEnabled(true);
+ QCOMPARE(testWidget->isSortingEnabled(), true);
+ QCOMPARE(testWidget->isSortingEnabled(), testWidget->header()->isSortIndicatorShown());
+
+ testWidget->setSortingEnabled(true);
+ QCOMPARE(testWidget->isSortingEnabled(), true);
+ QCOMPARE(testWidget->isSortingEnabled(), testWidget->header()->isSortIndicatorShown());
+
+ testWidget->setSortingEnabled(false);
+}
+
+void tst_QTreeWidget::addChild()
+{
+ QTreeWidget tree;
+ for (int x = 0; x < 2; ++x) {
+ QTreeWidget *view = x ? &tree : static_cast<QTreeWidget*>(0);
+ QTreeWidgetItem *item = new QTreeWidgetItem((QTreeWidget*)view);
+ QCOMPARE(item->childCount(), 0);
+
+ // try to add 0
+ item->addChild(0);
+ QCOMPARE(item->childCount(), 0);
+ QCOMPARE(item->indexOfChild(0), -1);
+
+ // add one at a time
+ QList<QTreeWidgetItem*> children;
+ for (int i = 0; i < 10; ++i) {
+ QTreeWidgetItem *child = new QTreeWidgetItem();
+ item->addChild(child);
+ QCOMPARE(item->childCount(), i+1);
+ QCOMPARE(item->child(i), child);
+ QCOMPARE(item->indexOfChild(child), i);
+ QCOMPARE(child->parent(), item);
+ QCOMPARE(child->treeWidget(), view);
+ item->addChild(child);
+ QCOMPARE(item->childCount(), i+1);
+ children.append(child);
+ }
+
+ // take them all
+ QList<QTreeWidgetItem*> taken = item->takeChildren();
+ QCOMPARE(taken, children);
+ QCOMPARE(item->childCount(), 0);
+ for (int i = 0; i < taken.count(); ++i) {
+ QCOMPARE(taken.at(i)->parent(), static_cast<QTreeWidgetItem*>(0));
+ QCOMPARE(taken.at(i)->treeWidget(), static_cast<QTreeWidget*>(0));
+ item->addChild(taken.at(i)); // re-add
+ }
+
+ // delete one at a time
+ while (!children.isEmpty()) {
+ QTreeWidgetItem *ti = children.takeFirst();
+ delete ti;
+ QCOMPARE(item->childCount(), children.count());
+ for (int i = 0; i < children.count(); ++i)
+ QCOMPARE(item->child(i), children.at(i));
+ }
+
+ // add none
+ {
+ int count = item->childCount();
+ item->addChildren(QList<QTreeWidgetItem*>());
+ QCOMPARE(item->childCount(), count);
+ }
+
+ // add many at a time
+ const int count = 10;
+ for (int i = 0; i < 100; i += count) {
+ QList<QTreeWidgetItem*> list;
+ for (int j = 0; j < count; ++j)
+ list << new QTreeWidgetItem(QStringList() << QString("%0").arg(j));
+ item->addChildren(list);
+ QCOMPARE(item->childCount(), count + i);
+ for (int j = 0; j < count; ++j) {
+ QCOMPARE(item->child(i+j), list.at(j));
+ QCOMPARE(item->child(i+j)->parent(), item);
+ }
+
+ item->addChildren(list);
+ QCOMPARE(item->childCount(), count + i);
+ }
+
+ if (!view)
+ delete item;
+ }
+}
+
+void tst_QTreeWidget::setData()
+{
+ {
+ QTreeWidgetItem *headerItem = new QTreeWidgetItem();
+ headerItem->setText(0, "Item1");
+ testWidget->setHeaderItem(headerItem);
+
+ QSignalSpy headerDataChangedSpy(
+ testWidget->model(), SIGNAL(headerDataChanged(Qt::Orientation, int, int)));
+ QSignalSpy dataChangedSpy(
+ testWidget->model(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)));
+ QSignalSpy itemChangedSpy(
+ testWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)));
+ headerItem->setText(0, "test");
+ QCOMPARE(dataChangedSpy.count(), 0);
+ QCOMPARE(headerDataChangedSpy.count(), 1);
+ QCOMPARE(itemChangedSpy.count(), 0); // no itemChanged() signal for header item
+
+ headerItem->setData(-1, -1, QVariant());
+ }
+
+ {
+ QSignalSpy itemChangedSpy(
+ testWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)));
+ QTreeWidgetItem *item = new QTreeWidgetItem();
+ testWidget->addTopLevelItem(item);
+ for (int x = 0; x < 2; ++x) {
+ for (int i = 1; i <= 2; ++i) {
+ for (int j = 0; j < 5; ++j) {
+ QVariantList args;
+ QString text = QString("text %0").arg(i);
+ item->setText(j, text);
+ QCOMPARE(item->text(j), text);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setText(j, text);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QPixmap pixmap(32, 32);
+ pixmap.fill((i == 1) ? Qt::red : Qt::green);
+ QIcon icon(pixmap);
+ item->setIcon(j, icon);
+ QCOMPARE(item->icon(j), icon);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setIcon(j, icon);
+ // #### shouldn't cause dataChanged()
+ QCOMPARE(itemChangedSpy.count(), 1);
+ itemChangedSpy.clear();
+
+ QString toolTip = QString("toolTip %0").arg(i);
+ item->setToolTip(j, toolTip);
+ QCOMPARE(item->toolTip(j), toolTip);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setToolTip(j, toolTip);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QString statusTip = QString("statusTip %0").arg(i);
+ item->setStatusTip(j, statusTip);
+ QCOMPARE(item->statusTip(j), statusTip);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setStatusTip(j, statusTip);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QString whatsThis = QString("whatsThis %0").arg(i);
+ item->setWhatsThis(j, whatsThis);
+ QCOMPARE(item->whatsThis(j), whatsThis);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setWhatsThis(j, whatsThis);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QSize sizeHint(64*i, 48*i);
+ item->setSizeHint(j, sizeHint);
+ QCOMPARE(item->sizeHint(j), sizeHint);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setSizeHint(j, sizeHint);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QFont font;
+ item->setFont(j, font);
+ QCOMPARE(item->font(j), font);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setFont(j, font);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ Qt::Alignment textAlignment((i == 1)
+ ? Qt::AlignLeft|Qt::AlignVCenter
+ : Qt::AlignRight);
+ item->setTextAlignment(j, textAlignment);
+ QCOMPARE(item->textAlignment(j), int(textAlignment));
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setTextAlignment(j, textAlignment);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QColor backgroundColor((i == 1) ? Qt::blue : Qt::yellow);
+ item->setBackground(j, backgroundColor);
+ QCOMPARE(item->background(j).color(), backgroundColor);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setBackground(j, backgroundColor);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QColor textColor((i == i) ? Qt::green : Qt::cyan);
+ item->setTextColor(j, textColor);
+ QCOMPARE(item->textColor(j), textColor);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setTextColor(j, textColor);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ Qt::CheckState checkState((i == 1) ? Qt::PartiallyChecked : Qt::Checked);
+ item->setCheckState(j, checkState);
+ QCOMPARE(item->checkState(j), checkState);
+ QCOMPARE(itemChangedSpy.count(), 1);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setCheckState(j, checkState);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ QCOMPARE(item->text(j), text);
+ QCOMPARE(item->icon(j), icon);
+ QCOMPARE(item->toolTip(j), toolTip);
+ QCOMPARE(item->statusTip(j), statusTip);
+ QCOMPARE(item->whatsThis(j), whatsThis);
+ QCOMPARE(item->sizeHint(j), sizeHint);
+ QCOMPARE(item->font(j), font);
+ QCOMPARE(item->textAlignment(j), int(textAlignment));
+ QCOMPARE(item->background(j).color(), backgroundColor);
+ QCOMPARE(item->textColor(j), textColor);
+ QCOMPARE(item->checkState(j), checkState);
+
+ QCOMPARE(qvariant_cast<QString>(item->data(j, Qt::DisplayRole)), text);
+ QCOMPARE(qvariant_cast<QIcon>(item->data(j, Qt::DecorationRole)), icon);
+ QCOMPARE(qvariant_cast<QString>(item->data(j, Qt::ToolTipRole)), toolTip);
+ QCOMPARE(qvariant_cast<QString>(item->data(j, Qt::StatusTipRole)), statusTip);
+ QCOMPARE(qvariant_cast<QString>(item->data(j, Qt::WhatsThisRole)), whatsThis);
+ QCOMPARE(qvariant_cast<QSize>(item->data(j, Qt::SizeHintRole)), sizeHint);
+ QCOMPARE(qvariant_cast<QFont>(item->data(j, Qt::FontRole)), font);
+ QCOMPARE(qvariant_cast<int>(item->data(j, Qt::TextAlignmentRole)), int(textAlignment));
+ QCOMPARE(qvariant_cast<QBrush>(item->data(j, Qt::BackgroundColorRole)), QBrush(backgroundColor));
+ QCOMPARE(qvariant_cast<QBrush>(item->data(j, Qt::BackgroundRole)), QBrush(backgroundColor));
+ QCOMPARE(qvariant_cast<QColor>(item->data(j, Qt::TextColorRole)), textColor);
+ QCOMPARE(qvariant_cast<int>(item->data(j, Qt::CheckStateRole)), int(checkState));
+
+ item->setBackground(j, pixmap);
+ QCOMPARE(item->background(j).texture(), pixmap);
+ QCOMPARE(qvariant_cast<QBrush>(item->data(j, Qt::BackgroundRole)).texture(), pixmap);
+ args = itemChangedSpy.takeFirst();
+ QCOMPARE(qvariant_cast<QTreeWidgetItem*>(args.at(0)), item);
+ QCOMPARE(qvariant_cast<int>(args.at(1)), j);
+ item->setBackground(j, pixmap);
+ QCOMPARE(itemChangedSpy.count(), 0);
+
+ item->setData(j, Qt::DisplayRole, QVariant());
+ item->setData(j, Qt::DecorationRole, QVariant());
+ item->setData(j, Qt::ToolTipRole, QVariant());
+ item->setData(j, Qt::StatusTipRole, QVariant());
+ item->setData(j, Qt::WhatsThisRole, QVariant());
+ item->setData(j, Qt::SizeHintRole, QVariant());
+ item->setData(j, Qt::FontRole, QVariant());
+ item->setData(j, Qt::TextAlignmentRole, QVariant());
+ item->setData(j, Qt::BackgroundColorRole, QVariant());
+ item->setData(j, Qt::TextColorRole, QVariant());
+ item->setData(j, Qt::CheckStateRole, QVariant());
+ QCOMPARE(itemChangedSpy.count(), 11);
+ itemChangedSpy.clear();
+
+ QCOMPARE(item->data(j, Qt::DisplayRole).toString(), QString());
+ QCOMPARE(item->data(j, Qt::DecorationRole), QVariant());
+ QCOMPARE(item->data(j, Qt::ToolTipRole), QVariant());
+ QCOMPARE(item->data(j, Qt::StatusTipRole), QVariant());
+ QCOMPARE(item->data(j, Qt::WhatsThisRole), QVariant());
+ QCOMPARE(item->data(j, Qt::SizeHintRole), QVariant());
+ QCOMPARE(item->data(j, Qt::FontRole), QVariant());
+ QCOMPARE(item->data(j, Qt::TextAlignmentRole), QVariant());
+ QCOMPARE(item->data(j, Qt::BackgroundColorRole), QVariant());
+ QCOMPARE(item->data(j, Qt::BackgroundRole), QVariant());
+ QCOMPARE(item->data(j, Qt::TextColorRole), QVariant());
+ QCOMPARE(item->data(j, Qt::CheckStateRole), QVariant());
+ }
+ }
+ }
+
+ // ### add more data types here
+
+ item->setData(0, Qt::DisplayRole, 5);
+ QCOMPARE(item->data(0, Qt::DisplayRole).type(), QVariant::Int);
+
+ item->setData(0, Qt::DisplayRole, "test");
+ QCOMPARE(item->data(0, Qt::DisplayRole).type(), QVariant::String);
+
+ item->setData(0, Qt::DisplayRole, 0.4);
+ QCOMPARE(item->data(0, Qt::DisplayRole).type(), QVariant::Double);
+
+ delete item;
+ }
+}
+
+void tst_QTreeWidget::itemData()
+{
+ QTreeWidget widget;
+ QTreeWidgetItem item(&widget);
+ widget.setColumnCount(2);
+ item.setFlags(item.flags() | Qt::ItemIsEditable);
+ item.setData(0, Qt::DisplayRole, QString("0"));
+ item.setData(0, Qt::CheckStateRole, Qt::PartiallyChecked);
+ item.setData(0, Qt::UserRole + 0, QString("1"));
+ item.setData(0, Qt::UserRole + 1, QString("2"));
+ item.setData(0, Qt::UserRole + 2, QString("3"));
+ item.setData(0, Qt::UserRole + 3, QString("4"));
+
+ QMap<int, QVariant> flags = widget.model()->itemData(widget.model()->index(0, 0));
+ QCOMPARE(flags.count(), 6);
+ QCOMPARE(flags[Qt::UserRole + 0].toString(), QString("1"));
+
+ flags = widget.model()->itemData(widget.model()->index(0, 1));
+ QCOMPARE(flags.count(), 0);
+}
+
+void tst_QTreeWidget::enableDisable()
+{
+ QTreeWidgetItem *itm = new QTreeWidgetItem();
+ for (int i = 0; i < 10; ++i)
+ new QTreeWidgetItem(itm);
+
+ // make sure all items are enabled
+ QVERIFY(itm->flags() & Qt::ItemIsEnabled);
+ for (int j = 0; j < itm->childCount(); ++j)
+ QVERIFY(itm->child(j)->flags() & Qt::ItemIsEnabled);
+
+ // disable root and make sure they are all disabled
+ itm->setFlags(itm->flags() & ~Qt::ItemIsEnabled);
+ QVERIFY(!(itm->flags() & Qt::ItemIsEnabled));
+ for (int k = 0; k < itm->childCount(); ++k)
+ QVERIFY(!(itm->child(k)->flags() & Qt::ItemIsEnabled));
+
+ // disable a child and make sure they are all still disabled
+ itm->child(5)->setFlags(itm->child(5)->flags() & ~Qt::ItemIsEnabled);
+ QVERIFY(!(itm->flags() & Qt::ItemIsEnabled));
+ for (int l = 0; l < itm->childCount(); ++l)
+ QVERIFY(!(itm->child(l)->flags() & Qt::ItemIsEnabled));
+
+ // enable root and make sure all items except one are enabled
+ itm->setFlags(itm->flags() | Qt::ItemIsEnabled);
+ QVERIFY(itm->flags() & Qt::ItemIsEnabled);
+ for (int m = 0; m < itm->childCount(); ++m)
+ if (m == 5)
+ QVERIFY(!(itm->child(m)->flags() & Qt::ItemIsEnabled));
+ else
+ QVERIFY(itm->child(m)->flags() & Qt::ItemIsEnabled);
+}
+
+void tst_QTreeWidget::match()
+{
+ QTreeWidget tree;
+ QModelIndexList list = tree.model()->match(QModelIndex(), Qt::DisplayRole, QString());
+
+ QVERIFY(list.isEmpty());
+}
+
+void tst_QTreeWidget::columnCount()
+{
+ int columnCountBefore = testWidget->columnCount();
+ testWidget->setColumnCount(-1);
+ QCOMPARE(testWidget->columnCount(), columnCountBefore);
+}
+
+void tst_QTreeWidget::setHeaderLabels()
+{
+ QStringList list = QString("a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z").split(",");
+ testWidget->setHeaderLabels(list);
+ QCOMPARE(testWidget->header()->count(), list.count());
+}
+
+void tst_QTreeWidget::setHeaderItem()
+{
+ testWidget->setHeaderItem(0);
+ QTreeWidgetItem *headerItem = new QTreeWidgetItem();
+
+ testWidget->setColumnCount(0);
+ QCOMPARE(testWidget->header()->count(), 0);
+ QCOMPARE(testWidget->columnCount(), 0);
+
+ headerItem->setText(0, "0");
+ headerItem->setText(1, "1");
+ testWidget->setHeaderItem(headerItem);
+ QTest::qWait(100);
+ QCOMPARE(testWidget->headerItem(), headerItem);
+ QCOMPARE(headerItem->treeWidget(), static_cast<QTreeWidget *>(testWidget));
+
+ QCOMPARE(testWidget->header()->count(), 2);
+ QCOMPARE(testWidget->columnCount(), 2);
+
+ headerItem->setText(2, "2");
+ QCOMPARE(testWidget->header()->count(), 3);
+ QCOMPARE(testWidget->columnCount(), 3);
+
+ delete headerItem;
+ testWidget->setColumnCount(3);
+ testWidget->setColumnCount(5);
+ QCOMPARE(testWidget->model()->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), QString("1"));
+ QCOMPARE(testWidget->model()->headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), QString("2"));
+ QCOMPARE(testWidget->model()->headerData(2, Qt::Horizontal, Qt::DisplayRole).toString(), QString("3"));
+ QCOMPARE(testWidget->model()->headerData(3, Qt::Horizontal, Qt::DisplayRole).toString(), QString("4"));
+ QCOMPARE(testWidget->model()->headerData(4, Qt::Horizontal, Qt::DisplayRole).toString(), QString("5"));
+
+ headerItem = new QTreeWidgetItem();
+ testWidget->setHeaderItem(headerItem);
+ testWidget->model()->insertColumns(0, 5, QModelIndex());
+ QCOMPARE(testWidget->model()->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString(), QString("1"));
+ QCOMPARE(testWidget->model()->headerData(1, Qt::Horizontal, Qt::DisplayRole).toString(), QString("2"));
+ QCOMPARE(testWidget->model()->headerData(2, Qt::Horizontal, Qt::DisplayRole).toString(), QString("3"));
+ QCOMPARE(testWidget->model()->headerData(3, Qt::Horizontal, Qt::DisplayRole).toString(), QString("4"));
+ QCOMPARE(testWidget->model()->headerData(4, Qt::Horizontal, Qt::DisplayRole).toString(), QString("5"));
+}
+
+void tst_QTreeWidget::itemWidget_data()
+{
+ editItem_data();
+}
+
+void tst_QTreeWidget::itemWidget()
+{
+ QFETCH(TreeItemList, topLevelItems);
+
+ QTreeWidget tree;
+ populate(&tree, topLevelItems, new TreeItem(QStringList() << "1" << "2"));
+ tree.show();
+
+ for (int x = 0; x < 2; ++x) {
+ QTreeWidgetItemIterator it(&tree);
+ while (QTreeWidgetItem *item = (*it++)) {
+ for (int col = 0; col < item->columnCount(); ++col) {
+ if (x == 0) {
+ QCOMPARE(tree.itemWidget(item, col), static_cast<QWidget*>(0));
+ QWidget *editor = new QLineEdit();
+ tree.setItemWidget(item, col, editor);
+ QCOMPARE(tree.itemWidget(item, col), editor);
+ tree.removeItemWidget(item, col);
+ QCOMPARE(tree.itemWidget(item, col), static_cast<QWidget*>(0));
+ } else {
+ // ### should you really be able to open a persistent
+ // editor for an item that isn't editable??
+ tree.openPersistentEditor(item, col);
+ QWidget *editor = qFindChild<QLineEdit*>(&tree);
+ QVERIFY(editor != 0);
+ tree.closePersistentEditor(item, col);
+ }
+ }
+ }
+ }
+}
+
+void tst_QTreeWidget::insertItemsWithSorting_data()
+{
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QStringList>("initialItems");
+ QTest::addColumn<QStringList>("insertItems");
+ QTest::addColumn<QStringList>("expectedItems");
+ QTest::addColumn<IntList>("expectedRows");
+
+ QTest::newRow("() + (a) = (a)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QStringList()
+ << (QStringList() << "a")
+ << (QStringList() << "a")
+ << IntList();
+ QTest::newRow("() + (c, b, a) = (a, b, c)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QStringList()
+ << (QStringList() << "c" << "b" << "a")
+ << (QStringList() << "a" << "b" << "c")
+ << IntList();
+ QTest::newRow("() + (a, b, c) = (c, b, a)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << QStringList()
+ << (QStringList() << "a" << "b" << "c")
+ << (QStringList() << "c" << "b" << "a")
+ << IntList();
+ QTest::newRow("(a) + (b) = (a, b)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QStringList("a")
+ << (QStringList() << "b")
+ << (QStringList() << "a" << "b")
+ << (IntList() << 0);
+ QTest::newRow("(a) + (b) = (b, a)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << QStringList("a")
+ << (QStringList() << "b")
+ << (QStringList() << "b" << "a")
+ << (IntList() << 1);
+ QTest::newRow("(a, c, b) + (d) = (a, b, c, d)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "b")
+ << (QStringList() << "d")
+ << (QStringList() << "a" << "b" << "c" << "d")
+ << (IntList() << 0 << 1 << 2);
+ QTest::newRow("(b, c, a) + (d) = (d, c, b, a)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QStringList() << "b" << "c" << "a")
+ << (QStringList() << "d")
+ << (QStringList() << "d" << "c" << "b" << "a")
+ << (IntList() << 1 << 2 << 3);
+ {
+ IntList ascendingRows;
+ IntList reverseRows;
+ QStringList ascendingItems;
+ QStringList reverseItems;
+ for (int i = 'a'; i <= 'z'; ++i) {
+ ascendingItems << QString("%0").arg(QLatin1Char(i));
+ reverseItems << QString("%0").arg(QLatin1Char('z' - i + 'a'));
+ ascendingRows << i - 'a';
+ reverseRows << 'z' - i + 'a';
+ }
+ QTest::newRow("() + (sorted items) = (sorted items)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << QStringList()
+ << ascendingItems
+ << ascendingItems
+ << IntList();
+ QTest::newRow("(sorted items) + () = (sorted items)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << ascendingItems
+ << QStringList()
+ << ascendingItems
+ << ascendingRows;
+ QTest::newRow("() + (ascending items) = (reverse items)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << QStringList()
+ << ascendingItems
+ << reverseItems
+ << IntList();
+ QTest::newRow("(reverse items) + () = (ascending items)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << reverseItems
+ << QStringList()
+ << ascendingItems
+ << ascendingRows;
+ QTest::newRow("(reverse items) + () = (reverse items)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << reverseItems
+ << QStringList()
+ << reverseItems
+ << ascendingRows;
+ }
+}
+
+void tst_QTreeWidget::insertItemsWithSorting()
+{
+ QFETCH(int, sortOrder);
+ QFETCH(QStringList, initialItems);
+ QFETCH(QStringList, insertItems);
+ QFETCH(QStringList, expectedItems);
+ QFETCH(IntList, expectedRows);
+
+ for (int method = 0; method < 5; ++method) {
+ QTreeWidget w;
+ w.setSortingEnabled(true);
+ w.sortItems(0, static_cast<Qt::SortOrder>(sortOrder));
+ for (int i = 0; i < initialItems.count(); ++i)
+ w.addTopLevelItem(new QTreeWidgetItem(QStringList() << initialItems.at(i)));
+
+ QAbstractItemModel *model = w.model();
+ QList<QPersistentModelIndex> persistent;
+ for (int j = 0; j < model->rowCount(QModelIndex()); ++j)
+ persistent << model->index(j, 0, QModelIndex());
+
+ switch (method) {
+ case 0:
+ // insert using item constructor
+ for (int i = 0; i < insertItems.size(); ++i)
+ new QTreeWidgetItem(&w, QStringList() << insertItems.at(i));
+ break;
+ case 1:
+ {
+ // insert using insertTopLevelItems()
+ QList<QTreeWidgetItem*> lst;
+ for (int i = 0; i < insertItems.size(); ++i)
+ lst << new QTreeWidgetItem(QStringList() << insertItems.at(i));
+ w.insertTopLevelItems(0, lst);
+ break;
+ }
+ case 2:
+ // insert using insertTopLevelItem()
+ for (int i = 0; i < insertItems.size(); ++i)
+ w.insertTopLevelItem(0, new QTreeWidgetItem(QStringList() << insertItems.at(i)));
+ break;
+ case 3:
+ {
+ // insert using addTopLevelItems()
+ QList<QTreeWidgetItem*> lst;
+ for (int i = 0; i < insertItems.size(); ++i)
+ lst << new QTreeWidgetItem(QStringList() << insertItems.at(i));
+ w.addTopLevelItems(lst);
+ break;
+ }
+ case 4:
+ // insert using addTopLevelItem()
+ for (int i = 0; i < insertItems.size(); ++i)
+ w.addTopLevelItem(new QTreeWidgetItem(QStringList() << insertItems.at(i)));
+ break;
+ }
+ QCOMPARE(w.topLevelItemCount(), expectedItems.count());
+ for (int i = 0; i < w.topLevelItemCount(); ++i)
+ QCOMPARE(w.topLevelItem(i)->text(0), expectedItems.at(i));
+
+ for (int k = 0; k < persistent.count(); ++k)
+ QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
+ }
+}
+
+void tst_QTreeWidget::insertExpandedItemsWithSorting_data()
+{
+ QTest::addColumn<QStringList>("parentText");
+ QTest::addColumn<QStringList>("childText");
+ QTest::addColumn<QStringList>("parentResult");
+ QTest::addColumn<QStringList>("childResult");
+ QTest::newRow("test 1")
+ << (QStringList() << "c" << "d" << "a" << "b")
+ << (QStringList() << "e" << "h" << "g" << "f")
+ << (QStringList() << "d" << "c" << "b" << "a")
+ << (QStringList() << "h" << "g" << "f" << "e");
+}
+
+// From Task 134978
+void tst_QTreeWidget::insertExpandedItemsWithSorting()
+{
+ QFETCH(QStringList, parentText);
+ QFETCH(QStringList, childText);
+ QFETCH(QStringList, parentResult);
+ QFETCH(QStringList, childResult);
+
+ // create a tree with autosorting enabled
+ CustomTreeWidget tree;
+ tree.setSortingEnabled(true);
+
+ // insert expanded items in unsorted order
+ QList<QTreeWidgetItem *> items;
+ for (int i = 0; i < parentText.count(); ++i) {
+ QTreeWidgetItem *parent = new QTreeWidgetItem(&tree, QStringList(parentText.at(i)));
+ parent->setExpanded(true);
+ QVERIFY(parent->isExpanded());
+ items << parent;
+ for (int j = 0; j < childText.count(); ++j) {
+ QTreeWidgetItem *child = new QTreeWidgetItem(parent, QStringList(childText.at(j)));
+ items << child;
+ }
+ QCOMPARE(parent->childCount(), childText.count());
+ QVERIFY(parent->isExpanded());
+ }
+ QVERIFY(tree.model()->rowCount() == parentText.count());
+
+ // verify that the items are still expanded
+ foreach (QTreeWidgetItem *item, items) {
+ if (item->childCount() > 0)
+ QVERIFY(item->isExpanded());
+ QModelIndex idx = tree.indexFromItem(const_cast<QTreeWidgetItem *>(item));
+ QVERIFY(idx.isValid());
+ //QRect rect = tree.visualRect(idx);
+ //QVERIFY(rect.isValid());
+ // ### it is not guarantied that the index is in the viewport
+ }
+
+ // verify that the tree is sorted
+ QAbstractItemModel *model = tree.model();
+ QList<QPersistentModelIndex> parents;
+ for (int i = 0; i < model->rowCount(QModelIndex()); ++i) {
+ QPersistentModelIndex parent = model->index(i, 0, QModelIndex());
+ parents << parent;
+ }
+ QList<QPersistentModelIndex> children;
+ for (int i = 0; i < model->rowCount(parents.first()); ++i) {
+ QPersistentModelIndex child = model->index(i, 0, parents.first());
+ children << child;
+ }
+ for (int i = 0; i < parentResult.count(); ++i) {
+ QTreeWidgetItem *item = tree.topLevelItem(i);
+ QCOMPARE(item->text(0), parentResult.at(i));
+ for (int j = 0; j < childResult.count(); ++j)
+ QCOMPARE(item->child(j)->text(0), childResult.at(j));
+ }
+}
+
+void tst_QTreeWidget::changeDataWithSorting_data()
+{
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QStringList>("initialItems");
+ QTest::addColumn<int>("itemIndex");
+ QTest::addColumn<QString>("newValue");
+ QTest::addColumn<QStringList>("expectedItems");
+ QTest::addColumn<IntList>("expectedRows");
+ QTest::addColumn<bool>("reorderingExpected");
+
+ QTest::newRow("change a to b in (a)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a")
+ << 0 << "b"
+ << (QStringList() << "b")
+ << (IntList() << 0)
+ << false;
+ QTest::newRow("change a to b in (a, c)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c")
+ << 0 << "b"
+ << (QStringList() << "b" << "c")
+ << (IntList() << 0 << 1)
+ << false;
+ QTest::newRow("change a to c in (a, b)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "b")
+ << 0 << "c"
+ << (QStringList() << "b" << "c")
+ << (IntList() << 1 << 0)
+ << true;
+ QTest::newRow("change c to a in (c, b)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QStringList() << "c" << "b")
+ << 0 << "a"
+ << (QStringList() << "b" << "a")
+ << (IntList() << 1 << 0)
+ << true;
+ QTest::newRow("change e to i in (a, c, e, g)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "e" << "g")
+ << 2 << "i"
+ << (QStringList() << "a" << "c" << "g" << "i")
+ << (IntList() << 0 << 1 << 3 << 2)
+ << true;
+ QTest::newRow("change e to a in (c, e, g, i)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "c" << "e" << "g" << "i")
+ << 1 << "a"
+ << (QStringList() << "a" << "c" << "g" << "i")
+ << (IntList() << 1 << 0 << 2 << 3)
+ << true;
+ QTest::newRow("change e to f in (c, e, g, i)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "c" << "e" << "g" << "i")
+ << 1 << "f"
+ << (QStringList() << "c" << "f" << "g" << "i")
+ << (IntList() << 0 << 1 << 2 << 3)
+ << false;
+}
+
+void tst_QTreeWidget::changeDataWithSorting()
+{
+ QFETCH(int, sortOrder);
+ QFETCH(QStringList, initialItems);
+ QFETCH(int, itemIndex);
+ QFETCH(QString, newValue);
+ QFETCH(QStringList, expectedItems);
+ QFETCH(IntList, expectedRows);
+ QFETCH(bool, reorderingExpected);
+
+ QTreeWidget w;
+ w.setSortingEnabled(true);
+ w.sortItems(0, static_cast<Qt::SortOrder>(sortOrder));
+ for (int i = 0; i < initialItems.count(); ++i)
+ w.addTopLevelItem(new QTreeWidgetItem(QStringList() << initialItems.at(i)));
+
+ QAbstractItemModel *model = w.model();
+ QList<QPersistentModelIndex> persistent;
+ for (int j = 0; j < model->rowCount(QModelIndex()); ++j)
+ persistent << model->index(j, 0, QModelIndex());
+
+ QSignalSpy dataChangedSpy(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)));
+ QSignalSpy layoutChangedSpy(model, SIGNAL(layoutChanged()));
+
+ QTreeWidgetItem *item = w.topLevelItem(itemIndex);
+ item->setText(0, newValue);
+ for (int i = 0; i < expectedItems.count(); ++i) {
+ QCOMPARE(w.topLevelItem(i)->text(0), expectedItems.at(i));
+ for (int j = 0; j < persistent.count(); ++j) {
+ if (persistent.at(j).row() == i) // the same toplevel row
+ QCOMPARE(persistent.at(j).internalPointer(), (void *)w.topLevelItem(i));
+ }
+ }
+
+ for (int k = 0; k < persistent.count(); ++k)
+ QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
+
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
+}
+
+void tst_QTreeWidget::changeDataWithStableSorting_data()
+{
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QStringList>("initialItems");
+ QTest::addColumn<int>("itemIndex");
+ QTest::addColumn<QString>("newValue");
+ QTest::addColumn<QStringList>("expectedItems");
+ QTest::addColumn<IntList>("expectedRows");
+ QTest::addColumn<bool>("reorderingExpected");
+ QTest::addColumn<bool>("forceChange");
+
+ QTest::newRow("change a to c in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 0 << "c"
+ << (QStringList() << "c" << "c" << "c" << "c" << "e")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << false;
+ QTest::newRow("change e to c in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 4 << "c"
+ << (QStringList() << "a" << "c" << "c" << "c" << "c")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << false;
+ QTest::newRow("change 1st c to c in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 1 << "c"
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << true;
+ QTest::newRow("change 2nd c to c in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 2 << "c"
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << true;
+ QTest::newRow("change 3rd c to c in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 3 << "c"
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << true;
+ QTest::newRow("change 1st c to c in (e, c, c, c, a)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QStringList() << "e" << "c" << "c" << "c" << "a")
+ << 1 << "c"
+ << (QStringList() << "e" << "c" << "c" << "c" << "a")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << true;
+ QTest::newRow("change 2nd c to c in (e, c, c, c, a)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QStringList() << "e" << "c" << "c" << "c" << "a")
+ << 2 << "c"
+ << (QStringList() << "e" << "c" << "c" << "c" << "a")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << true;
+ QTest::newRow("change 3rd c to c in (e, c, c, c, a)")
+ << static_cast<int>(Qt::DescendingOrder)
+ << (QStringList() << "e" << "c" << "c" << "c" << "a")
+ << 3 << "c"
+ << (QStringList() << "e" << "c" << "c" << "c" << "a")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << true;
+ QTest::newRow("change 1st c to b in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 1 << "b"
+ << (QStringList() << "a" << "b" << "c" << "c" << "e")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << false;
+ QTest::newRow("change 2nd c to b in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 2 << "b"
+ << (QStringList() << "a" << "b" << "c" << "c" << "e")
+ << (IntList() << 0 << 2 << 1 << 3 << 4)
+ << true
+ << false;
+ QTest::newRow("change 3rd c to b in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 3 << "b"
+ << (QStringList() << "a" << "b" << "c" << "c" << "e")
+ << (IntList() << 0 << 2 << 3 << 1 << 4)
+ << true
+ << false;
+ QTest::newRow("change 1st c to d in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 1 << "d"
+ << (QStringList() << "a" << "c" << "c" << "d" << "e")
+ << (IntList() << 0 << 3 << 1 << 2 << 4)
+ << true
+ << false;
+ QTest::newRow("change 2nd c to d in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 2 << "d"
+ << (QStringList() << "a" << "c" << "c" << "d" << "e")
+ << (IntList() << 0 << 1 << 3 << 2 << 4)
+ << true
+ << false;
+ QTest::newRow("change 3rd c to d in (a, c, c, c, e)")
+ << static_cast<int>(Qt::AscendingOrder)
+ << (QStringList() << "a" << "c" << "c" << "c" << "e")
+ << 3 << "d"
+ << (QStringList() << "a" << "c" << "c" << "d" << "e")
+ << (IntList() << 0 << 1 << 2 << 3 << 4)
+ << false
+ << false;
+}
+
+void tst_QTreeWidget::changeDataWithStableSorting()
+{
+ QFETCH(int, sortOrder);
+ QFETCH(QStringList, initialItems);
+ QFETCH(int, itemIndex);
+ QFETCH(QString, newValue);
+ QFETCH(QStringList, expectedItems);
+ QFETCH(IntList, expectedRows);
+ QFETCH(bool, reorderingExpected);
+ QFETCH(bool, forceChange);
+
+ class StableItem : public QTreeWidgetItem
+ {
+ public:
+ StableItem(const QStringList &strings) : QTreeWidgetItem(strings, QTreeWidgetItem::UserType) {}
+ void forceChangeData() {
+ emitDataChanged();
+ }
+ };
+
+ QTreeWidget w;
+ w.setSortingEnabled(true);
+ w.sortItems(0, static_cast<Qt::SortOrder>(sortOrder));
+ for (int i = 0; i < initialItems.count(); ++i)
+ w.addTopLevelItem(new StableItem(QStringList() << initialItems.at(i)));
+
+ QAbstractItemModel *model = w.model();
+ QList<QPersistentModelIndex> persistent;
+ for (int j = 0; j < model->rowCount(QModelIndex()); ++j)
+ persistent << model->index(j, 0, QModelIndex());
+
+ QSignalSpy dataChangedSpy(model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)));
+ QSignalSpy layoutChangedSpy(model, SIGNAL(layoutChanged()));
+
+ StableItem *item = static_cast<StableItem *>(w.topLevelItem(itemIndex));
+ item->setText(0, newValue);
+ if (forceChange)
+ item->forceChangeData();
+ for (int i = 0; i < expectedItems.count(); ++i) {
+ QCOMPARE(w.topLevelItem(i)->text(0), expectedItems.at(i));
+ for (int j = 0; j < persistent.count(); ++j) {
+ if (persistent.at(j).row() == i) // the same toplevel row
+ QCOMPARE(persistent.at(j).internalPointer(), (void *)w.topLevelItem(i));
+ }
+ }
+
+ for (int k = 0; k < persistent.count(); ++k)
+ QCOMPARE(persistent.at(k).row(), expectedRows.at(k));
+
+ QCOMPARE(dataChangedSpy.count(), 1);
+ QCOMPARE(layoutChangedSpy.count(), reorderingExpected ? 1 : 0);
+}
+
+void tst_QTreeWidget::itemOperatorLessThan()
+{
+ QTreeWidget tw;
+ tw.setColumnCount(2);
+ {
+ QTreeWidgetItem item1(&tw);
+ QTreeWidgetItem item2(&tw);
+ QCOMPARE(item1 < item2, false);
+ item1.setText(1, "a");
+ item2.setText(1, "b");
+ QCOMPARE(item1 < item2, false);
+ item1.setText(0, "a");
+ item2.setText(0, "b");
+ QCOMPARE(item1 < item2, true);
+ tw.sortItems(1, Qt::AscendingOrder);
+ item1.setText(0, "b");
+ item2.setText(0, "a");
+ QCOMPARE(item1 < item2, true);
+ tw.sortItems(0, Qt::AscendingOrder);
+ item1.setData(0, Qt::DisplayRole, 11);
+ item2.setData(0, Qt::DisplayRole, 2);
+ QCOMPARE(item1 < item2, false);
+ }
+}
+
+void tst_QTreeWidget::sortedIndexOfChild_data()
+{
+ QTest::addColumn<int>("sortOrder");
+ QTest::addColumn<QStringList>("itemTexts");
+ QTest::addColumn<QList<int> >("expectedIndexes");
+
+ QTest::newRow("three ascending")
+ << int(Qt::AscendingOrder)
+ << (QStringList() << "A" << "B" << "C")
+ << (QList<int>() << 0 << 1 << 2);
+
+
+ QTest::newRow("three descending")
+ << int(Qt::DescendingOrder)
+ << (QStringList() << "A" << "B" << "C")
+ << (QList<int>() << 2 << 1 << 0);
+}
+
+void tst_QTreeWidget::sortedIndexOfChild()
+{
+ QFETCH(int, sortOrder);
+ QFETCH(QStringList, itemTexts);
+ QFETCH(QList<int>, expectedIndexes);
+
+ QTreeWidget tw;
+ QList<QTreeWidgetItem*> itms;
+ QTreeWidgetItem *top = new QTreeWidgetItem(&tw, QStringList() << "top");
+
+ for (int i = 0; i < itemTexts.count(); ++i)
+ itms << new QTreeWidgetItem(top, QStringList() << itemTexts.at(i));
+
+ tw.sortItems(0, (Qt::SortOrder)sortOrder);
+ tw.expandAll();
+
+ QVERIFY(itms.count() == expectedIndexes.count());
+ for (int j = 0; j < expectedIndexes.count(); ++j)
+ QCOMPARE(top->indexOfChild(itms.at(j)), expectedIndexes.at(j));
+}
+
+void tst_QTreeWidget::expandAndCallapse()
+{
+ QTreeWidget tw;
+ QTreeWidgetItem *top = new QTreeWidgetItem(&tw, QStringList() << "top");
+ QTreeWidgetItem *p;
+ for (int i = 0; i < 10; ++i) {
+ p = new QTreeWidgetItem(top, QStringList() << QString("%1").arg(i));
+ for (int j = 0; j < 10; ++j)
+ new QTreeWidgetItem(p, QStringList() << QString("%1").arg(j));
+ }
+ QSignalSpy spy0(&tw, SIGNAL(itemExpanded(QTreeWidgetItem *)));
+ QSignalSpy spy1(&tw, SIGNAL(itemCollapsed(QTreeWidgetItem *)));
+
+
+ tw.expandItem(p);
+ tw.collapseItem(p);
+ tw.expandItem(p);
+ tw.expandItem(top);
+ tw.collapseItem(top);
+ tw.collapseItem(top);
+
+ QCOMPARE(spy0.count(), 3);
+ QCOMPARE(spy1.count(), 2);
+}
+
+void tst_QTreeWidget::setDisabled()
+{
+ QTreeWidget w;
+ QTreeWidgetItem *i1 = new QTreeWidgetItem();
+ QTreeWidgetItem *i2 = new QTreeWidgetItem(i1);
+ QTreeWidgetItem *i3 = new QTreeWidgetItem(i1);
+
+ QTreeWidgetItem *top = new QTreeWidgetItem(&w);
+ top->setDisabled(true);
+ top->addChild(i1);
+ QCOMPARE(i1->isDisabled(), true);
+ QCOMPARE(i2->isDisabled(), true);
+ QCOMPARE(i3->isDisabled(), true);
+
+ i1 = top->takeChild(0);
+ QCOMPARE(i1->isDisabled(), false);
+ QCOMPARE(i2->isDisabled(), false);
+ QCOMPARE(i3->isDisabled(), false);
+
+ top->addChild(i1);
+ QCOMPARE(i1->isDisabled(), true);
+ QCOMPARE(i2->isDisabled(), true);
+ QCOMPARE(i3->isDisabled(), true);
+
+ top->setDisabled(false);
+ QCOMPARE(i1->isDisabled(), false);
+ QCOMPARE(i2->isDisabled(), false);
+ QCOMPARE(i3->isDisabled(), false);
+
+
+
+ QList<QTreeWidgetItem*> children;
+ children.append(new QTreeWidgetItem());
+ children.append(new QTreeWidgetItem());
+ children.append(new QTreeWidgetItem());
+ i1 = top->takeChild(0);
+
+ top->addChildren(children);
+ QCOMPARE(top->child(0)->isDisabled(), false);
+ QCOMPARE(top->child(1)->isDisabled(), false);
+ QCOMPARE(top->child(1)->isDisabled(), false);
+
+ top->setDisabled(true);
+ QCOMPARE(top->child(0)->isDisabled(), true);
+ QCOMPARE(top->child(1)->isDisabled(), true);
+ QCOMPARE(top->child(1)->isDisabled(), true);
+
+ children = top->takeChildren();
+ QCOMPARE(children.at(0)->isDisabled(), false);
+ QCOMPARE(children.at(1)->isDisabled(), false);
+ QCOMPARE(children.at(1)->isDisabled(), false);
+
+}
+
+void tst_QTreeWidget::removeSelectedItem()
+{
+ QTreeWidget *w = new QTreeWidget();
+ w->setSortingEnabled(true);
+
+ QTreeWidgetItem *first = new QTreeWidgetItem();
+ first->setText(0, QLatin1String("D"));
+ w->addTopLevelItem(first);
+
+ QTreeWidgetItem *itm = new QTreeWidgetItem();
+ itm->setText(0, QLatin1String("D"));
+ w->addTopLevelItem(itm);
+
+ itm = new QTreeWidgetItem();
+ itm->setText(0, QLatin1String("C"));
+ w->addTopLevelItem(itm);
+ itm->setSelected(true);
+
+ itm = new QTreeWidgetItem();
+ itm->setText(0, QLatin1String("A"));
+ w->addTopLevelItem(itm);
+
+ //w->show();
+
+ QItemSelectionModel *selModel = w->selectionModel();
+ QCOMPARE(selModel->hasSelection(), true);
+ QCOMPARE(selModel->selectedRows().count(), 1);
+
+ QTreeWidgetItem *taken = w->takeTopLevelItem(2);
+ QCOMPARE(taken->text(0), QLatin1String("C"));
+
+ QCOMPARE(selModel->hasSelection(), false);
+ QCOMPARE(selModel->selectedRows().count(), 0);
+ QItemSelection sel = selModel->selection();
+ QCOMPARE(selModel->isSelected(w->model()->index(0,0)), false);
+
+ delete w;
+}
+
+class AnotherTreeWidget : public QTreeWidget
+{
+ Q_OBJECT
+public:
+ AnotherTreeWidget(QWidget *parent = 0) : QTreeWidget(parent) {}
+ void deleteCurrent() { if (currentItem()) delete currentItem(); }
+};
+
+void tst_QTreeWidget::removeCurrentItem()
+{
+ AnotherTreeWidget widget;
+ QObject::connect(widget.selectionModel(),
+ SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ &widget, SLOT(clear()));
+ QTreeWidgetItem *item = new QTreeWidgetItem(&widget);
+ widget.setCurrentItem(item);
+ widget.deleteCurrent();
+}
+
+void tst_QTreeWidget::removeCurrentItem_task186451()
+{
+ AnotherTreeWidget widget;
+ QTreeWidgetItem *item = new QTreeWidgetItem(&widget, QStringList() << "1");
+ QTreeWidgetItem *item2 = new QTreeWidgetItem(&widget, QStringList() << "2");
+ widget.setCurrentItem(item);
+ widget.deleteCurrent();
+
+ QVERIFY(item2->isSelected());
+ QCOMPARE(item2, widget.currentItem());
+}
+
+
+class TreeWidget : QTreeWidget {
+
+public:
+ QModelIndex indexFromItem(QTreeWidgetItem *item, int column = 0) const {
+ return QTreeWidget::indexFromItem(item, column);
+ }
+ QTreeWidgetItem *itemFromIndex(const QModelIndex &index) const {
+ return QTreeWidget::itemFromIndex(index);
+ }
+};
+
+
+void tst_QTreeWidget::randomExpand()
+{
+ QTreeWidget tree;
+ QTreeWidgetItem *item1 = new QTreeWidgetItem(&tree);
+ QTreeWidgetItem *item3 = new QTreeWidgetItem(&tree, item1);
+ new QTreeWidgetItem(item1);
+ new QTreeWidgetItem(item3);
+
+ tree.expandAll();
+
+ /*
+ item1
+ \- item2
+ item3
+ \- item4
+ */
+
+ QTreeWidgetItem *newItem1 = 0;
+ for (int i = 0; i < 100; i++) {
+ newItem1 = new QTreeWidgetItem(&tree, item1);
+ tree.setItemExpanded(newItem1, true);
+ QCOMPARE(tree.isItemExpanded(newItem1), true);
+
+ QTreeWidgetItem *x = new QTreeWidgetItem();
+ QCOMPARE(tree.isItemExpanded(newItem1), true);
+ newItem1->addChild(x);
+
+ QCOMPARE(tree.isItemExpanded(newItem1), true);
+ }
+
+}
+
+void tst_QTreeWidget::crashTest()
+{
+ QTreeWidget *tree = new QTreeWidget();
+ tree->setColumnCount(1);
+ tree->show();
+
+ QTreeWidgetItem *item1 = new QTreeWidgetItem(tree);
+ item1->setText(0, "item1");
+ tree->setItemExpanded(item1, true);
+ QTreeWidgetItem *item2 = new QTreeWidgetItem(item1);
+ item2->setText(0, "item2");
+
+ QTreeWidgetItem *item3 = new QTreeWidgetItem(tree, item1);
+ item3->setText(0, "item3");
+ tree->setItemExpanded(item3, true);
+ QTreeWidgetItem *item4 = new QTreeWidgetItem(item3);
+ item4->setText(0, "item4");
+
+ QTreeWidgetItem *item5 = new QTreeWidgetItem(tree, item3);
+ item5->setText(0, "item5");
+ tree->setItemExpanded(item5, true);
+ QTreeWidgetItem *item6 = new QTreeWidgetItem(item5);
+ item6->setText(0, "item6");
+
+ for (int i = 0; i < 1000; i++) {
+ QTreeWidgetItem *newItem1 = new QTreeWidgetItem(tree, item1);
+ newItem1->setText(0, "newItem");
+ QTreeWidgetItem *newItem2 = new QTreeWidgetItem(newItem1);
+ newItem2->setText(0, "subItem1");
+ QTreeWidgetItem *newItem3 = new QTreeWidgetItem(newItem1, newItem2);
+ newItem3->setText(0, "subItem2");
+ delete item3;
+ item3 = newItem1;
+ }
+ QApplication::instance()->processEvents();
+
+ delete tree;
+}
+
+class CrashWidget : public QTreeWidget
+{
+public:
+ CrashWidget(QWidget *parent = 0) : QTreeWidget(parent), i(0) {
+ setSortingEnabled(true);
+ timerId = startTimer(10);
+ }
+ int i;
+protected:
+ void timerEvent(QTimerEvent * event) {
+ if (event->timerId() == timerId) {
+ QTreeWidgetItem *newItem = new QTreeWidgetItem((QStringList() << QString::number(i++)));
+ m_list.append(newItem);
+ insertTopLevelItem(0, newItem);
+ while (m_list.count() > 10)
+ delete m_list.takeFirst();
+ }
+ QTreeWidget::timerEvent(event);
+ }
+private:
+ int timerId;
+ QList<QTreeWidgetItem*> m_list;
+};
+
+void tst_QTreeWidget::sortAndSelect()
+{
+ CrashWidget w;
+ w.resize(1, 1);
+ w.show();
+ while (w.i < 100) {
+ QApplication::processEvents();
+ if (w.i & 16) {
+ QPoint pt = w.viewport()->rect().center();
+ QTest::mouseClick(w.viewport(), Qt::LeftButton, Qt::NoModifier, pt);
+ }
+ }
+ QVERIFY(true);
+}
+
+void tst_QTreeWidget::defaultRowSizes()
+{
+ QTreeWidget *tw = new QTreeWidget();
+ tw->setIconSize(QSize(50, 50));
+ tw->setColumnCount(6);
+ for (int i=0; i<10; ++i) {
+ QTreeWidgetItem *it = new QTreeWidgetItem(tw);
+ for (int j=0; j<tw->columnCount() - 1; ++j) {
+ it->setText(j, "This is a test");
+ }
+ QPixmap icon = tw->style()->standardPixmap((QStyle::StandardPixmap)(i + QStyle::SP_TitleBarMenuButton));
+ if (icon.isNull())
+ QSKIP("No pixmap found on current style, skipping this test.", SkipSingle);
+ it->setIcon(tw->columnCount() - 1,
+ icon.scaled(tw->iconSize()));
+ }
+ tw->resize(100,100);
+ tw->show();
+ QApplication::processEvents();
+
+ QRect visualRect = tw->visualItemRect(tw->topLevelItem(0));
+ QVERIFY(visualRect.height() >= 50);
+}
+
+void tst_QTreeWidget::task191552_rtl()
+{
+ Qt::LayoutDirection oldDir = qApp->layoutDirection();
+ qApp->setLayoutDirection(Qt::RightToLeft);
+
+ QTreeWidget tw;
+ tw.setColumnCount(1);
+ QTreeWidgetItem *item = new QTreeWidgetItem(&tw);
+ item->setText(0, "item 1");
+ item->setCheckState(0, Qt::Checked);
+ QCOMPARE(item->checkState(0), Qt::Checked);
+ tw.show();
+ QTest::qWait(50);
+ QStyleOptionViewItem opt;
+ opt.initFrom(&tw);
+ opt.rect = tw.visualItemRect(item);
+ const QRect checkRect = tw.style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, &tw);
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::NoModifier, checkRect.center());
+ QTest::qWait(200);
+ QCOMPARE(item->checkState(0), Qt::Unchecked);
+
+ qApp->setLayoutDirection(oldDir);
+}
+
+void tst_QTreeWidget::task203673_selection()
+{
+ //we try to change the selection by rightclick + ctrl
+ //it should do anything when using ExtendedSelection
+
+ QTreeWidget tw;
+ tw.setColumnCount(1);
+ QTreeWidgetItem *item1 = new QTreeWidgetItem(&tw);
+ item1->setText(0, "item 1");
+ tw.setSelectionMode(QTreeView::ExtendedSelection);
+
+ QPoint center = tw.visualItemRect(item1).center();
+ QCOMPARE(item1->isSelected(), false);
+
+ QTest::mouseClick(tw.viewport(), Qt::RightButton, Qt::ControlModifier, center);
+ QCOMPARE(item1->isSelected(), false);
+
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ControlModifier, center);
+ QCOMPARE(item1->isSelected(), true);
+
+ QTest::mouseClick(tw.viewport(), Qt::RightButton, Qt::ControlModifier, center);
+ QCOMPARE(item1->isSelected(), true); //it shouldn't change
+
+ QTest::mouseClick(tw.viewport(), Qt::LeftButton, Qt::ControlModifier, center);
+ QCOMPARE(item1->isSelected(), false);
+}
+
+
+void tst_QTreeWidget::rootItemFlags()
+{
+ QTreeWidget tw;
+ tw.setColumnCount(1);
+ QTreeWidgetItem *item = new QTreeWidgetItem(&tw);
+ item->setText(0, "item 1");
+
+ QVERIFY(tw.invisibleRootItem()->flags() & Qt::ItemIsDropEnabled);
+
+ tw.invisibleRootItem()->setFlags(tw.invisibleRootItem()->flags() & ~Qt::ItemIsDropEnabled);
+
+ QVERIFY(!(tw.invisibleRootItem()->flags() & Qt::ItemIsDropEnabled));
+}
+
+void tst_QTreeWidget::task218661_setHeaderData()
+{
+ //We check that setting header data out of bounds returns false
+ //and doesn't increase the size of the model
+ QTreeWidget tw;
+ tw.setColumnCount(1);
+ QCOMPARE(tw.columnCount(), 1);
+
+ QCOMPARE(tw.model()->setHeaderData(99999, Qt::Horizontal, QVariant()), false);
+
+ QCOMPARE(tw.columnCount(), 1);
+}
+
+void tst_QTreeWidget::task245280_sortChildren()
+{
+ QTreeWidget tw;
+ tw.setColumnCount(2);
+
+ QTreeWidgetItem top(&tw);
+ top.setText(0,"Col 0");
+ top.setText(1,"Col 1");
+ QTreeWidgetItem item1(&top);
+ item1.setText(0,"X");
+ item1.setText(1,"0");
+ QTreeWidgetItem item2(&top);
+ item2.setText(0,"A");
+ item2.setText(1,"4");
+ QTreeWidgetItem item3(&top);
+ item3.setText(0,"E");
+ item3.setText(1,"1");
+ QTreeWidgetItem item4(&top);
+ item4.setText(0,"Z");
+ item4.setText(1,"3");
+ QTreeWidgetItem item5(&top);
+ item5.setText(0,"U");
+ item5.setText(1,"2");
+ tw.expandAll();
+ tw.show();
+ top.sortChildren(1,Qt::AscendingOrder);
+
+ for (int i = 0; i < top.childCount(); ++i)
+ QCOMPARE(top.child(i)->text(1), QString::number(i));
+}
+
+void tst_QTreeWidget::task253109_itemHeight()
+{
+ QTreeWidget treeWidget;
+ treeWidget.setColumnCount(1);
+ treeWidget.show();
+ QTest::qWait(200);
+
+ QTreeWidgetItem item(&treeWidget);
+ class MyWidget : public QWidget
+ {
+ virtual QSize sizeHint() const { return QSize(200,100); }
+ } w;
+ treeWidget.setItemWidget(&item, 0, &w);
+
+ QTest::qWait(200);
+ QCOMPARE(w.geometry(), treeWidget.visualItemRect(&item));
+
+}
+
+void tst_QTreeWidget::task206367_duplication()
+{
+ QWidget topLevel;
+ QTreeWidget treeWidget(&topLevel);
+ topLevel.show();
+ treeWidget.resize(200, 200);
+
+ treeWidget.setSortingEnabled(true);
+ QTreeWidgetItem* rootItem = new QTreeWidgetItem( &treeWidget, QStringList("root") );
+ for (int nFile = 0; nFile < 2; nFile++ ) {
+ QTreeWidgetItem* itemFile = new QTreeWidgetItem(rootItem, QStringList(QString::number(nFile)));
+ for (int nRecord = 0; nRecord < 2; nRecord++)
+ new QTreeWidgetItem(itemFile , QStringList(QString::number(nRecord)));
+ itemFile->setExpanded(true);
+ }
+ rootItem->setExpanded(true);
+ QTest::qWait(2000);
+
+ //there should be enough room for 2x2 items. If there is a scrollbar, it means the items are duplicated
+ QVERIFY(!treeWidget.verticalScrollBar()->isVisible());
+
+}
+
+void tst_QTreeWidget::itemSelectionChanged()
+{
+ QVERIFY(testWidget);
+ if(testWidget->topLevelItem(0))
+ QVERIFY(testWidget->topLevelItem(0)->isSelected());
+}
+
+void tst_QTreeWidget::selectionOrder()
+{
+ testWidget->setColumnCount(1);
+ QList<QTreeWidgetItem *> items;
+ for (int i = 0; i < 10; ++i)
+ items.append(new QTreeWidgetItem((QTreeWidget*)0, QStringList(QString("item: %1").arg(i))));
+ testWidget->insertTopLevelItems(0, items);
+
+ QModelIndex idx = testWidget->indexFromItem(items[0]);
+ connect(testWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
+ testWidget->selectionModel()->select(idx, QItemSelectionModel::SelectCurrent);
+ disconnect(testWidget, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
+}
+
+void tst_QTreeWidget::setSelectionModel()
+{
+ QTreeWidget tree;
+ for(int i = 0; i < 3; ++i)
+ new QTreeWidgetItem(&tree, QStringList(QString::number(i)));
+ QItemSelectionModel selection(tree.model());
+ selection.select(tree.model()->index(1,0), QItemSelectionModel::Select);
+ tree.setSelectionModel(&selection);
+ QCOMPARE(tree.topLevelItem(1)->isSelected(), true);
+}
+
+void tst_QTreeWidget::task217309()
+{
+ QTreeWidgetItem item;
+ item.setFlags(item.flags() | Qt::ItemIsTristate);
+ QTreeWidgetItem subitem1;
+ subitem1.setFlags(subitem1.flags() | Qt::ItemIsTristate);
+ QTreeWidgetItem subitem2;
+ subitem2.setFlags(subitem2.flags() | Qt::ItemIsTristate);
+ item.addChild(&subitem1);
+ item.addChild(&subitem2);
+ subitem1.setCheckState(0, Qt::Checked);
+ subitem2.setCheckState(0, Qt::Unchecked);
+
+ QVERIFY(item.data(0, Qt::CheckStateRole) == Qt::PartiallyChecked);
+
+ subitem2.setCheckState(0, Qt::PartiallyChecked);
+ QVERIFY(item.data(0, Qt::CheckStateRole) == Qt::PartiallyChecked);
+
+ subitem2.setCheckState(0, Qt::Checked);
+ QVERIFY(item.data(0, Qt::CheckStateRole) == Qt::Checked);
+}
+
+class TreeWidgetItem : public QTreeWidgetItem
+{
+
+public:
+ void _emitDataChanged() { emitDataChanged(); }
+
+};
+
+void tst_QTreeWidget::emitDataChanged()
+{
+
+ QTreeWidget *tree = new QTreeWidget;
+ QSignalSpy spy(tree, SIGNAL(itemChanged(QTreeWidgetItem *, int)));
+ TreeWidgetItem *item = new TreeWidgetItem();
+ tree->insertTopLevelItem(0, item);
+ item->_emitDataChanged();
+ QCOMPARE(spy.count(), 1);
+
+}
+
+void tst_QTreeWidget::setCurrentItemExpandsParent()
+{
+ QTreeWidget w;
+ w.setColumnCount(1);
+ QTreeWidgetItem *i1 = new QTreeWidgetItem(&w, QStringList() << "parent");
+ QTreeWidgetItem *i2 = new QTreeWidgetItem(i1, QStringList() << "child");
+ QVERIFY(!i2->isExpanded());
+ QVERIFY(w.currentItem() == 0);
+ w.setCurrentItem(i2);
+ QVERIFY(!i2->isExpanded());
+ QCOMPARE(w.currentItem(), i2);
+}
+
+void tst_QTreeWidget::task239150_editorWidth()
+{
+ //we check that an item with no text will get an editor with a correct size
+ QTreeWidget tree;
+
+ QStyleOptionFrameV2 opt;
+ opt.init(&tree);
+ const int minWidth = tree.style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(0, 0).
+ expandedTo(QApplication::globalStrut()), 0).width();
+
+ {
+ QTreeWidgetItem item;
+ item.setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
+ tree.addTopLevelItem(&item);
+ QVERIFY(tree.itemWidget(&item, 0) == 0);
+ tree.editItem(&item);
+ QVERIFY(tree.itemWidget(&item, 0));
+ QVERIFY(tree.itemWidget(&item, 0)->width() >= minWidth);
+ }
+
+ //now let's test it with an item with a lot of text
+ {
+ QTreeWidgetItem item;
+ item.setText(0, "foooooooooooooooooooooooo");
+ item.setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
+ tree.addTopLevelItem(&item);
+ QVERIFY(tree.itemWidget(&item, 0) == 0);
+ tree.editItem(&item);
+ QVERIFY(tree.itemWidget(&item, 0));
+ QVERIFY(tree.itemWidget(&item, 0)->width() >= minWidth + tree.fontMetrics().width(item.text(0)));
+ }
+}
+
+
+
+void tst_QTreeWidget::setTextUpdate()
+{
+ QTreeWidget treeWidget;
+ treeWidget.setColumnCount(2);
+
+ class MyItemDelegate : public QStyledItemDelegate
+ {
+ public:
+ MyItemDelegate() : numPaints(0) { }
+ void paint(QPainter *painter,
+ const QStyleOptionViewItem &option, const QModelIndex &index) const
+ {
+ numPaints++;
+ QStyledItemDelegate::paint(painter, option, index);
+ }
+
+ mutable int numPaints;
+ } delegate;
+
+ treeWidget.setItemDelegate(&delegate);
+ treeWidget.show();
+ QStringList strList;
+ strList << "variable1" << "0";
+ QTreeWidgetItem *item = new QTreeWidgetItem(strList);
+ treeWidget.insertTopLevelItem(0, item);
+ QTest::qWait(50);
+ QTRY_VERIFY(delegate.numPaints > 0);
+ delegate.numPaints = 0;
+
+ item->setText(1, "42");
+ QApplication::processEvents();
+ QTRY_VERIFY(delegate.numPaints > 0);
+}
+
+void tst_QTreeWidget::taskQTBUG2844_visualItemRect()
+{
+ CustomTreeWidget tree;
+ tree.resize(150, 100);
+ tree.setColumnCount(3);
+ QTreeWidgetItem item(&tree);
+
+ QRect itemRect = tree.visualItemRect(&item);
+
+ QRect rectCol0 = tree.visualRect(tree.indexFromItem(&item, 0));
+ QRect rectCol1 = tree.visualRect(tree.indexFromItem(&item, 1));
+ QRect rectCol2 = tree.visualRect(tree.indexFromItem(&item, 2));
+
+ QCOMPARE(tree.visualItemRect(&item), rectCol0 | rectCol2);
+ tree.setColumnHidden(2, true);
+ QCOMPARE(tree.visualItemRect(&item), rectCol0 | rectCol1);
+}
+
+void tst_QTreeWidget::setChildIndicatorPolicy()
+{
+ QTreeWidget treeWidget;
+ treeWidget.setColumnCount(1);
+
+ class MyItemDelegate : public QStyledItemDelegate
+ {
+ public:
+ MyItemDelegate() : numPaints(0), expectChildren(false) { }
+ void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+ {
+ numPaints++;
+ QCOMPARE(!(option.state & QStyle::State_Children), !expectChildren);
+ QStyledItemDelegate::paint(painter, option, index);
+ }
+ mutable int numPaints;
+ bool expectChildren;
+ } delegate;
+
+ treeWidget.setItemDelegate(&delegate);
+ treeWidget.show();
+
+ QTreeWidgetItem *item = new QTreeWidgetItem(QStringList("Hello"));
+ treeWidget.insertTopLevelItem(0, item);
+ QTest::qWait(50);
+ QTRY_VERIFY(delegate.numPaints > 0);
+
+ delegate.numPaints = 0;
+ delegate.expectChildren = true;
+ item->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator);
+ QApplication::processEvents();
+ QTRY_COMPARE(delegate.numPaints, 1);
+
+ delegate.numPaints = 0;
+ delegate.expectChildren = false;
+ item->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicatorWhenChildless);
+ QApplication::processEvents();
+ QTRY_COMPARE(delegate.numPaints, 1);
+
+ delegate.numPaints = 0;
+ delegate.expectChildren = true;
+ new QTreeWidgetItem(item);
+ QApplication::processEvents();
+ QTRY_COMPARE(delegate.numPaints, 1);
+
+ delegate.numPaints = 0;
+ delegate.expectChildren = false;
+ item->setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
+ QApplication::processEvents();
+ QTRY_COMPARE(delegate.numPaints, 1);
+}
+
+
+
+QTEST_MAIN(tst_QTreeWidget)
+#include "tst_qtreewidget.moc"