summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/itemviews/qtreewidget
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/itemviews/qtreewidget')
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/.gitignore1
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/qtreewidget.pro3
-rw-r--r--tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp3349
3 files changed, 3353 insertions, 0 deletions
diff --git a/tests/auto/widgets/itemviews/qtreewidget/.gitignore b/tests/auto/widgets/itemviews/qtreewidget/.gitignore
new file mode 100644
index 0000000000..08c63b4b52
--- /dev/null
+++ b/tests/auto/widgets/itemviews/qtreewidget/.gitignore
@@ -0,0 +1 @@
+tst_qtreewidget
diff --git a/tests/auto/widgets/itemviews/qtreewidget/qtreewidget.pro b/tests/auto/widgets/itemviews/qtreewidget/qtreewidget.pro
new file mode 100644
index 0000000000..763c0d3c63
--- /dev/null
+++ b/tests/auto/widgets/itemviews/qtreewidget/qtreewidget.pro
@@ -0,0 +1,3 @@
+load(qttest_p4)
+QT += widgets
+SOURCES += tst_qtreewidget.cpp
diff --git a/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
new file mode 100644
index 0000000000..5e1faf97c4
--- /dev/null
+++ b/tests/auto/widgets/itemviews/qtreewidget/tst_qtreewidget.cpp
@@ -0,0 +1,3349 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <qtreewidget.h>
+#include <qtreewidgetitemiterator.h>
+#include <qapplication.h>
+#include <qeventloop.h>
+#include <qdebug.h>
+#include <qheaderview.h>
+#include <qlineedit.h>
+#include <QScrollBar>
+#include <QStyledItemDelegate>
+
+//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"