From 2a601a3e3388663f275ecf4be980610c5992a7b4 Mon Sep 17 00:00:00 2001 From: Gennady Pospelov <g.pospelov@fz-juelich.de> Date: Tue, 14 Nov 2017 15:42:48 +0100 Subject: [PATCH] New ModelUtils function to iterate through children only if user callback allows. --- GUI/coregui/Models/ModelUtils.cpp | 16 ++++++++++++ GUI/coregui/Models/ModelUtils.h | 6 ++++- Tests/UnitTests/GUI/TestGUI.cpp | 2 +- Tests/UnitTests/GUI/TestModelUtils.h | 39 +++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/GUI/coregui/Models/ModelUtils.cpp b/GUI/coregui/Models/ModelUtils.cpp index 9f34a10d6a5..eaf53ab916c 100644 --- a/GUI/coregui/Models/ModelUtils.cpp +++ b/GUI/coregui/Models/ModelUtils.cpp @@ -31,3 +31,19 @@ void ModelUtils::iterate(const QModelIndex& index, const QAbstractItemModel* mod for (int j = 0; j < model->columnCount(index); ++j) iterate(model->index(i, j, index), model, fun); } + +void ModelUtils::iterate_if(const QModelIndex& index, const QAbstractItemModel* model, + const std::function<bool (const QModelIndex&)>& fun) +{ + bool proceed_with_children(true); + if (index.isValid()) + proceed_with_children = fun(index); + + if (!model->hasChildren(index) || !proceed_with_children) + return; + + for (int i = 0; i < model->rowCount(index); ++i) + for (int j = 0; j < model->columnCount(index); ++j) + iterate_if(model->index(i, j, index), model, fun); + +} diff --git a/GUI/coregui/Models/ModelUtils.h b/GUI/coregui/Models/ModelUtils.h index c99f7d399dd..ef9306dca27 100644 --- a/GUI/coregui/Models/ModelUtils.h +++ b/GUI/coregui/Models/ModelUtils.h @@ -30,7 +30,11 @@ namespace ModelUtils BA_CORE_API_ void iterate(const QModelIndex& index, const QAbstractItemModel* model, const std::function<void(const QModelIndex&)>& fun); -} +//! Iterates through all model indices and calls user function. +//! If function returns false for given index, iteration will not go down to children. +BA_CORE_API_ void iterate_if(const QModelIndex& index, const QAbstractItemModel* model, + const std::function<bool(const QModelIndex&)>& fun); +} #endif // MODELUTILS_H diff --git a/Tests/UnitTests/GUI/TestGUI.cpp b/Tests/UnitTests/GUI/TestGUI.cpp index fa44f095501..96afb70d414 100644 --- a/Tests/UnitTests/GUI/TestGUI.cpp +++ b/Tests/UnitTests/GUI/TestGUI.cpp @@ -96,7 +96,7 @@ int main(int argc, char** argv) { // tests.add<TestParticleCoreShell>(); // tests.add<TestPropertyRepeater>(); // tests.add<TestSessionItemController>(); -// tests.add<TestModelUtils>(); + tests.add<TestModelUtils>(); tests.add<TestComponentProxyModel>(); tests.add<TestProxyModelStrategy>(); diff --git a/Tests/UnitTests/GUI/TestModelUtils.h b/Tests/UnitTests/GUI/TestModelUtils.h index d5f9ed6b75f..46e27303743 100644 --- a/Tests/UnitTests/GUI/TestModelUtils.h +++ b/Tests/UnitTests/GUI/TestModelUtils.h @@ -3,17 +3,32 @@ #include "SessionModel.h" #include "item_constants.h" #include "VectorItem.h" +#include "LayerItem.h" #include <QVector> #include <QDebug> class TestModelUtils : public QObject { Q_OBJECT -public: +private: + + //! Returns true if model contains given item using iterate_if procedure. + bool modelContainsItem(SessionModel* model, SessionItem* selectedItem) + { + bool result = false; + ModelUtils::iterate_if(QModelIndex(), model, [&](const QModelIndex& index) -> bool { + SessionItem* item = model->itemForIndex(index); + if(item == selectedItem) + result = true; + return item->isVisible(); + }); + return result; + } private slots: void test_emptyModel(); void test_vectorItem(); + void test_iterateIf(); }; //! Testing iteration over empty model. @@ -57,3 +72,25 @@ inline void TestModelUtils::test_vectorItem() QCOMPARE(model.itemForIndex(indices.front()), vectorItem); QCOMPARE(model.itemForIndex(indices.back()), vectorItem->getItem(VectorItem::P_Z)); } + +//! Tests iteration when some children is invisible. + +inline void TestModelUtils::test_iterateIf() +{ + SessionModel model("TestModel"); + SessionItem* multilayer = model.insertNewItem(Constants::MultiLayerType); + SessionItem* layer = model.insertNewItem(Constants::LayerType, model.indexOfItem(multilayer)); + SessionItem* thicknessItem = layer->getItem(LayerItem::P_THICKNESS); + + layer->setVisible(true); + QVERIFY(modelContainsItem(&model, layer) == true); + QVERIFY(modelContainsItem(&model, thicknessItem) == true); + + // Setting layer invisible will hide its children from iteration. + // Layer itself still will be visible. + layer->setVisible(false); + + layer->setVisible(false); + QVERIFY(modelContainsItem(&model, layer) == true); + QVERIFY(modelContainsItem(&model, thicknessItem) == false); +} -- GitLab