Skip to content
Snippets Groups Projects
Commit aafc92f6 authored by Pospelov, Gennady's avatar Pospelov, Gennady
Browse files

Identity proxy strategy was extracted to separate class.

parent 6efa62d5
No related branches found
No related tags found
No related merge requests found
......@@ -17,12 +17,14 @@
#include "ComponentProxyModel.h"
#include "SessionModel.h"
#include "ModelUtils.h"
#include "ProxyModelStrategy.h"
#include <functional>
#include <QDebug>
ComponentProxyModel::ComponentProxyModel(QObject* parent)
: QAbstractProxyModel(parent)
, m_model(nullptr)
, m_proxyStrategy(new IndentityProxyStrategy)
{
}
......@@ -70,7 +72,7 @@ QModelIndex ComponentProxyModel::mapToSource(const QModelIndex& proxyIndex) cons
if (!proxyIndex.isValid())
return QModelIndex();
return m_sourceToProxy.key(proxyIndex);
return m_proxyStrategy->sourceToProxy().key(proxyIndex);
}
QModelIndex ComponentProxyModel::mapFromSource(const QModelIndex& sourceIndex) const
......@@ -78,7 +80,7 @@ QModelIndex ComponentProxyModel::mapFromSource(const QModelIndex& sourceIndex) c
if (!sourceIndex.isValid())
return QModelIndex();
return m_sourceToProxy.value(sourceIndex);
return m_proxyStrategy->sourceToProxy().value(sourceIndex);
}
QModelIndex ComponentProxyModel::index(int row, int column, const QModelIndex& parent) const
......@@ -87,7 +89,7 @@ QModelIndex ComponentProxyModel::index(int row, int column, const QModelIndex& p
if (parent.isValid())
sourceParent = mapToSource(parent);
QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(m_proxySourceParent);
QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(m_proxyStrategy->proxySourceParent());
while (it.hasNext()) {
it.next();
if (it.value() == sourceParent && it.key().row() == row &&
......@@ -99,7 +101,7 @@ QModelIndex ComponentProxyModel::index(int row, int column, const QModelIndex& p
QModelIndex ComponentProxyModel::parent(const QModelIndex& child) const
{
QModelIndex sourceParent = m_proxySourceParent.value(child);
QModelIndex sourceParent = m_proxyStrategy->proxySourceParent().value(child);
if (sourceParent.isValid())
return mapFromSource(sourceParent);
......@@ -111,7 +113,7 @@ int ComponentProxyModel::rowCount(const QModelIndex& parent) const
QModelIndex sourceParent;
if (parent.isValid())
sourceParent = mapToSource(parent);
QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(m_proxySourceParent);
QMapIterator<QPersistentModelIndex, QPersistentModelIndex> it(m_proxyStrategy->proxySourceParent());
QSet<int> rows;
while (it.hasNext()) {
......@@ -177,24 +179,6 @@ void ComponentProxyModel::sourceRowsInserted(const QModelIndex& parent, int star
void ComponentProxyModel::buildModelMap()
{
m_sourceToProxy.clear();
m_proxySourceParent.clear();
ModelUtils::iterate(QModelIndex(), m_model, [=](const QModelIndex& index){
SessionItem* item = m_model->itemForIndex(index);
// qDebug() << "XXX index" << index << "index.parent" << index.parent();
QPersistentModelIndex proxy = createIndex(index.row(), index.column(), item);
m_sourceToProxy.insert(QPersistentModelIndex(index), proxy);
QPersistentModelIndex sourceParent;
if (index.parent().isValid())
sourceParent = index.parent();
// qDebug() << "YYY proxy" << proxy << "sourceParent" << sourceParent;
m_proxySourceParent.insert(proxy, sourceParent);
// qDebug() << " ";
});
m_proxyStrategy->buildModelMap(m_model, this);
layoutChanged();
}
......@@ -18,11 +18,14 @@
#define COMPONENTPROXYMODEL_H
#include "WinDllMacros.h"
#include "ProxyModelStrategy.h"
#include <QAbstractProxyModel>
#include <QPersistentModelIndex>
#include <QMap>
#include <memory>
class SessionModel;
class ProxyModelStrategy;
//! Proxy model to adjust SessionModel for component editor (right bottom corner of SampleView
//! and similar).
......@@ -33,6 +36,8 @@ class SessionModel;
class BA_CORE_API_ ComponentProxyModel : public QAbstractProxyModel
{
Q_OBJECT
friend class ProxyModelStrategy;
public:
ComponentProxyModel(QObject* parent = nullptr);
......@@ -60,11 +65,8 @@ private slots:
private:
void buildModelMap();
//!< Mapping of proxy model indices to indices in source model
QMap<QPersistentModelIndex, QPersistentModelIndex> m_sourceToProxy;
//!< Mapping of proxy model indices to indices of parent in source model
QMap<QPersistentModelIndex, QPersistentModelIndex> m_proxySourceParent;
SessionModel* m_model;
std::unique_ptr<ProxyModelStrategy> m_proxyStrategy;
};
#endif // COMPONENTPROXYMODEL_H
......
// ************************************************************************** //
//
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @file GUI/coregui/Models/ProxyModelStrategy.cpp
//! @brief Implements class ProxyModelStrategy
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2016
//! @authors Scientific Computing Group at MLZ Garching
//! @authors Céline Durniak, Marina Ganeva, David Li, Gennady Pospelov
//! @authors Walter Van Herck, Joachim Wuttke
//
// ************************************************************************** //
#include "ProxyModelStrategy.h"
#include "ModelUtils.h"
#include "ComponentProxyModel.h"
const ProxyModelStrategy::map_t& ProxyModelStrategy::sourceToProxy()
{
return m_sourceToProxy;
}
const ProxyModelStrategy::map_t& ProxyModelStrategy::proxySourceParent()
{
return m_proxySourceParent;
}
//! Method to ask proxy to create an index using friendship of ProxyModelStrategy
//! and ComponentProxyModel.
QModelIndex ProxyModelStrategy::createIndex(ComponentProxyModel* proxy, int nrow, int ncol,
void* adata)
{
return proxy->createIndex(nrow, ncol, adata);
}
//! Builds one-to-one mapping for source and proxy.
void IndentityProxyStrategy::buildModelMap(QAbstractItemModel* source, ComponentProxyModel* proxy)
{
m_sourceToProxy.clear();
m_proxySourceParent.clear();
ModelUtils::iterate(QModelIndex(), source, [=](const QModelIndex& index) {
QPersistentModelIndex proxyIndex
= createIndex(proxy, index.row(), index.column(), index.internalPointer());
m_sourceToProxy.insert(QPersistentModelIndex(index), proxyIndex);
QPersistentModelIndex sourceParent;
if (index.parent().isValid())
sourceParent = index.parent();
m_proxySourceParent.insert(proxyIndex, sourceParent);
});
}
// ************************************************************************** //
//
// BornAgain: simulate and fit scattering at grazing incidence
//
//! @file GUI/coregui/Models/ProxyModelStrategy.h
//! @brief Defines class ProxyModelStrategy
//!
//! @homepage http://www.bornagainproject.org
//! @license GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2016
//! @authors Scientific Computing Group at MLZ Garching
//! @authors Céline Durniak, Marina Ganeva, David Li, Gennady Pospelov
//! @authors Walter Van Herck, Joachim Wuttke
//
// ************************************************************************** //
#ifndef PROXYMODELSTRATEGY_H
#define PROXYMODELSTRATEGY_H
#include "WinDllMacros.h"
#include <QPersistentModelIndex>
class QAbstractItemModel;
class ComponentProxyModel;
//! Base class for proxy strategies in ComponentProxyModel.
class BA_CORE_API_ ProxyModelStrategy
{
public:
using map_t = QMap<QPersistentModelIndex, QPersistentModelIndex>;
virtual ~ProxyModelStrategy() = default;
virtual void buildModelMap(QAbstractItemModel* source, ComponentProxyModel* proxy) = 0;
const map_t& sourceToProxy();
const map_t& proxySourceParent();
protected:
QModelIndex createIndex(ComponentProxyModel* proxy, int nrow, int ncol, void* adata);
//!< Mapping of proxy model indices to indices in source model
QMap<QPersistentModelIndex, QPersistentModelIndex> m_sourceToProxy;
//!< Mapping of proxy model indices to indices of parent in source model
QMap<QPersistentModelIndex, QPersistentModelIndex> m_proxySourceParent;
};
//! Strategy for ComponentProxyModel which makes it identical to source model.
class BA_CORE_API_ IndentityProxyStrategy : public ProxyModelStrategy
{
public:
void buildModelMap(QAbstractItemModel* source, ComponentProxyModel* proxy);
};
#endif // ProxyModelStrategy
......@@ -33,6 +33,7 @@
#include "TestSessionItemController.h"
#include "TestModelUtils.h"
#include "TestComponentProxyModel.h"
#include "TestProxyModelStrategy.h"
#include <memory>
class GUITestFactory {
......@@ -95,8 +96,9 @@ 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>();
return tests.runAll(argc, argv);
}
#include <QtTest>
#include "ModelUtils.h"
#include "SessionModel.h"
#include "item_constants.h"
#include "ComponentProxyModel.h"
#include "ProxyModelStrategy.h"
#include "VectorItem.h"
#include "ParticleItem.h"
#include "FormFactorItems.h"
#include <QSignalSpy>
#include <QDebug>
class TestProxyModelStrategy : public QObject
{
Q_OBJECT
public:
private slots:
void test_identityStrategy();
void test_identityStrategyParticle();
};
//! Checking the mapping in the case of PropertyItem inserted in the source.
inline void TestProxyModelStrategy::test_identityStrategy()
{
SessionModel model("TestModel");
ComponentProxyModel proxy;
IndentityProxyStrategy strategy;
QCOMPARE(strategy.sourceToProxy().size(), 0);
QCOMPARE(strategy.proxySourceParent().size(), 0);
// building the map of empty source
strategy.buildModelMap(&model, &proxy);
QCOMPARE(strategy.sourceToProxy().size(), 0);
QCOMPARE(strategy.proxySourceParent().size(), 0);
// building map when simple item
SessionItem* item = model.insertNewItem(Constants::PropertyType);
strategy.buildModelMap(&model, &proxy);
QCOMPARE(strategy.sourceToProxy().size(), 2);
QCOMPARE(strategy.proxySourceParent().size(), 2);
// Checking of persistent indices of source and proxy
auto it = strategy.sourceToProxy().begin();
// index of source, col=0
QCOMPARE(it.key().row(), 0);
QCOMPARE(it.key().column(), 0);
QCOMPARE(it.key().internalPointer(), item);
// index of proxy, col=0
QCOMPARE(it.value().row(), 0);
QCOMPARE(it.value().column(), 0);
QCOMPARE(it.value().internalPointer(), item);
++it;
// index of source, col=1
QCOMPARE(it.key().row(), 0);
QCOMPARE(it.key().column(), 1);
QCOMPARE(it.key().internalPointer(), item);
// index of proxy, col=1
QCOMPARE(it.value().row(), 0);
QCOMPARE(it.value().column(), 1);
QCOMPARE(it.value().internalPointer(), item);
// Checking parent of proxy
it = strategy.proxySourceParent().begin();
QCOMPARE(it.key().row(), 0);
QCOMPARE(it.key().column(), 0);
QCOMPARE(it.key().internalPointer(), item);
QVERIFY(it.value() == QModelIndex());
}
//! Checking the mapping in the case of ParticleItem inserted in the source.
inline void TestProxyModelStrategy::test_identityStrategyParticle()
{
SessionModel model("TestModel");
ComponentProxyModel proxy;
IndentityProxyStrategy strategy;
SessionItem* item = model.insertNewItem(Constants::ParticleType);
// building the map of empty source
strategy.buildModelMap(&model, &proxy);
SessionItem* group = item->getItem(ParticleItem::P_FORM_FACTOR);
SessionItem* ffItem = item->getGroupItem(ParticleItem::P_FORM_FACTOR);
QVERIFY(ffItem->parent() == group);
QVERIFY(ffItem->modelType() == Constants::CylinderType);
// Checking "real" parent of proxy index related to form factor.
// For identity model we are testing, it has to be just group property.
auto ffProxyIndex = strategy.sourceToProxy().value(model.indexOfItem(ffItem));
auto parentOfProxy = strategy.proxySourceParent().value(ffProxyIndex);
QVERIFY(parentOfProxy == model.indexOfItem(group));
// Checking "real" parent of Cylinders radius. It has to be CylinderItem
SessionItem* radiusItem = ffItem->getItem(CylinderItem::P_RADIUS);
auto radiusProxyIndex = strategy.sourceToProxy().value(model.indexOfItem(radiusItem));
parentOfProxy = strategy.proxySourceParent().value(radiusProxyIndex);
QVERIFY(parentOfProxy == model.indexOfItem(ffItem));
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment