From 1a7ff8184cb8f3edd2efd069b5a84aa71e7063fb Mon Sep 17 00:00:00 2001 From: Tobias Knopff <t.knopff@fz-juelich.de> Date: Thu, 1 Jul 2021 15:53:18 +0200 Subject: [PATCH] Make ItemWithMaterial::P_MATERIAL private --- GUI/Models/GUIDomainSampleVisitor.cpp | 11 ++--- GUI/Models/ItemWithMaterial.cpp | 20 +++++++++ GUI/Models/ItemWithMaterial.h | 9 +++- GUI/Models/LayerItem.cpp | 2 +- GUI/Models/LayerItem.h | 2 +- GUI/Models/MaterialItemUtils.cpp | 13 ------ GUI/Models/MaterialItemUtils.h | 1 - GUI/Models/MaterialPropertyController.cpp | 42 +++++++++---------- GUI/Models/MaterialPropertyController.h | 3 +- GUI/Models/ParticleItem.cpp | 2 +- GUI/Models/TransformToDomain.cpp | 6 +-- GUI/Models/TransformToDomain.h | 3 +- GUI/Views/RealSpaceWidgets/TransformTo3D.cpp | 2 +- GUI/Views/SampleDesigner/ILayerView.cpp | 23 +++------- Tests/UnitTests/GUI/TestComponentUtils.cpp | 4 +- Tests/UnitTests/GUI/TestLayerItems.cpp | 3 +- .../GUI/TestMaterialPropertyController.cpp | 14 +++---- 17 files changed, 78 insertions(+), 82 deletions(-) diff --git a/GUI/Models/GUIDomainSampleVisitor.cpp b/GUI/Models/GUIDomainSampleVisitor.cpp index c3bbf452757..7f1c4e0b857 100644 --- a/GUI/Models/GUIDomainSampleVisitor.cpp +++ b/GUI/Models/GUIDomainSampleVisitor.cpp @@ -44,6 +44,9 @@ #include "Sample/Particle/ParticleCoreShell.h" #include "Sample/SoftParticle/SoftParticles.h" +#include <boost/polymorphic_cast.hpp> +using boost::polymorphic_downcast; + namespace { SessionItem* AddFormFactorItem(SessionItem* parent, const QString& model_type) { @@ -111,8 +114,7 @@ void GUIDomainSampleVisitor::visit(const Layer* sample) layer_index == 0 ? nullptr : multilayer->layerInterface(layer_index - 1); LayerItem* layer_item = m_sampleModel->insertItem<LayerItem>(parent); - layer_item->setItemValue(LayerItem::P_MATERIAL, - createMaterialFromDomain(sample->material()).variant()); + layer_item->setMaterial(createMaterialFromDomain(sample->material())); GUI::Transform::FromDomain::setLayerItem(layer_item, sample, top_interface); @@ -132,9 +134,8 @@ void GUIDomainSampleVisitor::visit(const MultiLayer* sample) void GUIDomainSampleVisitor::visit(const Particle* sample) { - auto particle_item = InsertIParticle(sample, "Particle"); - particle_item->setItemValue(ParticleItem::P_MATERIAL, - createMaterialFromDomain(sample->material()).variant()); + auto particle_item = polymorphic_downcast<ParticleItem*>(InsertIParticle(sample, "Particle")); + particle_item->setMaterial(createMaterialFromDomain(sample->material())); } void GUIDomainSampleVisitor::visit(const ParticleCoreShell* sample) diff --git a/GUI/Models/ItemWithMaterial.cpp b/GUI/Models/ItemWithMaterial.cpp index 1cbc1ef15e9..7da9728b87d 100644 --- a/GUI/Models/ItemWithMaterial.cpp +++ b/GUI/Models/ItemWithMaterial.cpp @@ -19,6 +19,26 @@ const QString ItemWithMaterial::P_MATERIAL = "Material"; ItemWithMaterial::~ItemWithMaterial() = default; +ExternalProperty ItemWithMaterial::material() const +{ + return getItemValue(P_MATERIAL).value<ExternalProperty>(); +} + +void ItemWithMaterial::setMaterial(const ExternalProperty& material) +{ + setItemValue(P_MATERIAL, material.variant()); +} + +bool ItemWithMaterial::isMaterialPropertyName(const QString& name) +{ + return name == P_MATERIAL; +} + +SessionItem* ItemWithMaterial::materialItem() const +{ + return getItem(P_MATERIAL); +} + ItemWithMaterial::ItemWithMaterial(const QString& model_type) : SessionGraphicsItem(model_type) { addProperty(P_MATERIAL, GUI::Model::MaterialItemUtils::defaultMaterialProperty().variant()) diff --git a/GUI/Models/ItemWithMaterial.h b/GUI/Models/ItemWithMaterial.h index 67ce71af883..797794d7701 100644 --- a/GUI/Models/ItemWithMaterial.h +++ b/GUI/Models/ItemWithMaterial.h @@ -16,13 +16,20 @@ #define BORNAGAIN_GUI_MODELS_ITEMWITHMATERIAL_H #include "GUI/Models/SessionGraphicsItem.h" +#include "GUI/Models/ExternalProperty.h" class BA_CORE_API_ ItemWithMaterial : public SessionGraphicsItem { -public: +private: static const QString P_MATERIAL; +public: virtual ~ItemWithMaterial() = 0; + ExternalProperty material() const; + void setMaterial(const ExternalProperty& material); + static bool isMaterialPropertyName(const QString& name); + SessionItem* materialItem() const; + protected: ItemWithMaterial(const QString& model_type); }; diff --git a/GUI/Models/LayerItem.cpp b/GUI/Models/LayerItem.cpp index 9524c1d7db1..586b097228a 100644 --- a/GUI/Models/LayerItem.cpp +++ b/GUI/Models/LayerItem.cpp @@ -50,7 +50,7 @@ LayerItem::LayerItem() : ItemWithMaterial(M_TYPE) QVector<SessionItem*> LayerItem::materialPropertyItems() { QVector<SessionItem*> result; - if (auto property = getItem(LayerItem::P_MATERIAL)) + if (auto property = materialItem()) result.push_back(property); for (auto layout : getItems(LayerItem::T_LAYOUTS)) result.append(GUI::Model::MaterialItemUtils::materialPropertyItems(layout)); diff --git a/GUI/Models/LayerItem.h b/GUI/Models/LayerItem.h index dfa34a6b90b..3b701d24283 100644 --- a/GUI/Models/LayerItem.h +++ b/GUI/Models/LayerItem.h @@ -43,7 +43,7 @@ public: template <typename T> T* setRoughnessType(); SessionItem* roughness() const; SessionItem* roughnessItem() const; - + private: void updateAppearance(SessionItem* new_parent); }; diff --git a/GUI/Models/MaterialItemUtils.cpp b/GUI/Models/MaterialItemUtils.cpp index 116f00d0895..3fcaee1ae54 100644 --- a/GUI/Models/MaterialItemUtils.cpp +++ b/GUI/Models/MaterialItemUtils.cpp @@ -109,19 +109,6 @@ MaterialItem* GUI::Model::MaterialItemUtils::findMaterial(const ExternalProperty return material; } -//! Returns material tag for given item. Returns empty string, if item doesn't have materials. - -QString GUI::Model::MaterialItemUtils::materialTag(const SessionItem& item) -{ - QString result; - if (item.modelType() == "Particle") { - result = ParticleItem::P_MATERIAL; - } else if (item.hasModelType<LayerItem>()) { - result = LayerItem::P_MATERIAL; - } - return result; -} - //! Returns list of model types which contains registered MaterialProperty. QStringList GUI::Model::MaterialItemUtils::materialRelatedModelTypes() diff --git a/GUI/Models/MaterialItemUtils.h b/GUI/Models/MaterialItemUtils.h index 70372926e5c..45510318bc2 100644 --- a/GUI/Models/MaterialItemUtils.h +++ b/GUI/Models/MaterialItemUtils.h @@ -36,7 +36,6 @@ std::unique_ptr<Material> createDomainMaterial(const ExternalProperty& material_ const MaterialItemContainer& container); MaterialItem* findMaterial(const ExternalProperty& material_property); -QString materialTag(const SessionItem& item); QStringList materialRelatedModelTypes(); //! Constructs material property corresponding to given material. diff --git a/GUI/Models/MaterialPropertyController.cpp b/GUI/Models/MaterialPropertyController.cpp index a0b847af278..a497f2721e5 100644 --- a/GUI/Models/MaterialPropertyController.cpp +++ b/GUI/Models/MaterialPropertyController.cpp @@ -13,6 +13,7 @@ // ************************************************************************************************ #include "GUI/Models/MaterialPropertyController.h" +#include "GUI/Models/ItemWithMaterial.h" #include "GUI/Models/MaterialItemUtils.h" #include "GUI/Models/MaterialModel.h" #include "GUI/Models/ModelPath.h" @@ -20,6 +21,9 @@ #include "GUI/Models/SampleModel.h" #include <QVector> +#include <boost/polymorphic_cast.hpp> +using boost::polymorphic_downcast; + MaterialPropertyController::MaterialPropertyController(QObject* parent) : QObject(parent), m_materialModel(nullptr), m_sampleModel(nullptr) { @@ -45,19 +49,16 @@ void MaterialPropertyController::setModels(MaterialModel* materialModel, SampleM void MaterialPropertyController::onMaterialModelLoad() { - for (auto sampleItem : relatedSampleItems()) { - QString tag = GUI::Model::MaterialItemUtils::materialTag(*sampleItem); - ASSERT(!tag.isEmpty()); - - ExternalProperty property = sampleItem->getItemValue(tag).value<ExternalProperty>(); + for (ItemWithMaterial* sampleItem : relatedSampleItems()) { + ExternalProperty property = sampleItem->material(); if (MaterialItem* material = m_materialModel->materialFromIdentifier(property.identifier())) { ExternalProperty new_property = GUI::Model::MaterialItemUtils::materialProperty(*material); - sampleItem->setItemValue(tag, new_property.variant()); + sampleItem->setMaterial(new_property); } else { ExternalProperty undefined; - sampleItem->setItemValue(tag, undefined.variant()); + sampleItem->setMaterial(undefined); } } } @@ -71,15 +72,12 @@ void MaterialPropertyController::onMaterialDataChanged(const QModelIndex& topLef if (auto materialItem = dynamic_cast<const MaterialItem*>( GUI::Model::Path::ancestor(changedItem, MaterialItem::M_TYPE))) { - for (auto sampleItem : relatedSampleItems()) { - QString tag = GUI::Model::MaterialItemUtils::materialTag(*sampleItem); - ASSERT(!tag.isEmpty()); - - ExternalProperty property = sampleItem->getItemValue(tag).value<ExternalProperty>(); + for (ItemWithMaterial* sampleItem : relatedSampleItems()) { + ExternalProperty property = sampleItem->material(); if (property.identifier() == materialItem->identifier()) { ExternalProperty new_property = GUI::Model::MaterialItemUtils::materialProperty(*materialItem); - sampleItem->setItemValue(tag, new_property.variant()); + sampleItem->setMaterial(new_property); } } } @@ -103,32 +101,30 @@ void MaterialPropertyController::onMaterialRowsAboutToBeRemoved(const QModelInde } // rewriting MaterialProperty in corresponding sample items - for (auto sampleItem : relatedSampleItems()) { - QString tag = GUI::Model::MaterialItemUtils::materialTag(*sampleItem); - ASSERT(!tag.isEmpty()); - - ExternalProperty property = sampleItem->getItemValue(tag).value<ExternalProperty>(); + for (ItemWithMaterial* sampleItem : relatedSampleItems()) { + ExternalProperty property = sampleItem->material(); if (identifiersToDelete.contains(property.identifier())) { ExternalProperty undefined; - sampleItem->setItemValue(tag, undefined.variant()); + sampleItem->setMaterial(undefined); } } } //! Returns vector of SessionItems having MaterialProperty on board. -QVector<SessionItem*> MaterialPropertyController::relatedSampleItems() +QVector<ItemWithMaterial*> MaterialPropertyController::relatedSampleItems() { - static QStringList materialRelated = GUI::Model::MaterialItemUtils::materialRelatedModelTypes(); + static const QStringList materialRelated = + GUI::Model::MaterialItemUtils::materialRelatedModelTypes(); - QVector<SessionItem*> result; + QVector<ItemWithMaterial*> result; GUI::Model::ItemUtils::iterate(QModelIndex(), m_sampleModel, [&](const QModelIndex& index) { if (index.column() != 0) return; if (SessionItem* item = m_sampleModel->itemForIndex(index)) if (materialRelated.contains(item->modelType())) - result.push_back(item); + result.push_back(polymorphic_downcast<ItemWithMaterial*>(item)); }); return result; diff --git a/GUI/Models/MaterialPropertyController.h b/GUI/Models/MaterialPropertyController.h index 634b4e9f3e8..8f77ce2804a 100644 --- a/GUI/Models/MaterialPropertyController.h +++ b/GUI/Models/MaterialPropertyController.h @@ -17,6 +17,7 @@ #include <QObject> +class ItemWithMaterial; class MaterialModel; class SampleModel; class SessionItem; @@ -39,7 +40,7 @@ private slots: void onMaterialRowsAboutToBeRemoved(const QModelIndex& parent, int first, int last); private: - QVector<SessionItem*> relatedSampleItems(); + QVector<ItemWithMaterial*> relatedSampleItems(); MaterialModel* m_materialModel; SampleModel* m_sampleModel; diff --git a/GUI/Models/ParticleItem.cpp b/GUI/Models/ParticleItem.cpp index 0f8e21bd4ec..573c16eddea 100644 --- a/GUI/Models/ParticleItem.cpp +++ b/GUI/Models/ParticleItem.cpp @@ -74,7 +74,7 @@ std::unique_ptr<Particle> ParticleItem::createParticle() const QVector<SessionItem*> ParticleItem::materialPropertyItems() { - auto item = getItem(P_MATERIAL); + auto item = materialItem(); if (!item) return {}; return {item}; diff --git a/GUI/Models/TransformToDomain.cpp b/GUI/Models/TransformToDomain.cpp index 703c8ece2c5..9f7189099b7 100644 --- a/GUI/Models/TransformToDomain.cpp +++ b/GUI/Models/TransformToDomain.cpp @@ -48,13 +48,13 @@ void setParameterDistributionToSimulation(ParameterDistribution::WhichParameter std::unique_ptr<ScanResolution> createScanResolution(const SessionItem* item); } // namespace -std::unique_ptr<Material> GUI::Transform::ToDomain::createDomainMaterial(const SessionItem& item) +std::unique_ptr<Material> GUI::Transform::ToDomain::createDomainMaterial +(const ItemWithMaterial& item) { auto parent_job = GUI::Model::JobFunctions::findJobItem(&item); const MaterialItemContainer* container = parent_job ? parent_job->materialContainerItem() : nullptr; - QString tag = GUI::Model::MaterialItemUtils::materialTag(item); - ExternalProperty property = item.getItemValue(tag).value<ExternalProperty>(); + ExternalProperty property = item.material(); return container ? GUI::Model::MaterialItemUtils::createDomainMaterial(property, *container) : GUI::Model::MaterialItemUtils::createDomainMaterial(property); } diff --git a/GUI/Models/TransformToDomain.h b/GUI/Models/TransformToDomain.h index 77fb11b047b..d07bf70d0e4 100644 --- a/GUI/Models/TransformToDomain.h +++ b/GUI/Models/TransformToDomain.h @@ -30,6 +30,7 @@ class AngularSpecScan; class BeamDistributionItem; class BeamItem; class GISASSimulation; +class ItemWithMaterial; class LayerItem; class Material; class MaterialItemContainer; @@ -38,7 +39,7 @@ class ISimulation; namespace GUI::Transform::ToDomain { -std::unique_ptr<Material> createDomainMaterial(const SessionItem& item); +std::unique_ptr<Material> createDomainMaterial(const ItemWithMaterial& item); std::unique_ptr<IParticle> createIParticle(const SessionItem& item); std::unique_ptr<Layer> createLayer(const LayerItem& item); std::unique_ptr<LayerRoughness> createLayerRoughness(const SessionItem& item); diff --git a/GUI/Views/RealSpaceWidgets/TransformTo3D.cpp b/GUI/Views/RealSpaceWidgets/TransformTo3D.cpp index 3b6589357e6..1423a166237 100644 --- a/GUI/Views/RealSpaceWidgets/TransformTo3D.cpp +++ b/GUI/Views/RealSpaceWidgets/TransformTo3D.cpp @@ -66,7 +66,7 @@ GUI::View::TransformTo3D::createLayer(const LayerItem& layerItem, GUI::RealSpace::Range(static_cast<float>(-s2), static_cast<float>(+s2)), GUI::RealSpace::Range(static_cast<float>(ztop), static_cast<float>(zbottom)))); - QColor color = layerItem.getItemValue(LayerItem::P_MATERIAL).value<ExternalProperty>().color(); + QColor color = layerItem.material().color(); color.setAlphaF(.3); result->color = color; diff --git a/GUI/Views/SampleDesigner/ILayerView.cpp b/GUI/Views/SampleDesigner/ILayerView.cpp index fa3b4146ace..2e477056237 100644 --- a/GUI/Views/SampleDesigner/ILayerView.cpp +++ b/GUI/Views/SampleDesigner/ILayerView.cpp @@ -52,7 +52,7 @@ void ILayerView::onPropertyChange(const QString& propertyName) { if (LayerItem::isThicknessPropertyName(propertyName)) { updateHeight(); - } else if (propertyName == LayerItem::P_MATERIAL) { + } else if (LayerItem::isMaterialPropertyName(propertyName)) { updateColor(); updateLabel(); } @@ -72,15 +72,9 @@ void ILayerView::updateHeight() void ILayerView::updateColor() { - if (m_item->isTag(LayerItem::P_MATERIAL)) { - QVariant v = m_item->getItemValue(LayerItem::P_MATERIAL); - if (v.isValid()) { - ExternalProperty mp = v.value<ExternalProperty>(); - setColor(mp.color()); - update(); - } else { - ASSERT(0); - } + if (LayerItem* item = dynamic_cast<LayerItem*>(m_item)) { + setColor(item->material().color()); + update(); } } @@ -92,13 +86,8 @@ void ILayerView::updateLabel() NodeEditorPort* port = getInputPorts()[0]; QString material = ""; - if (m_item->isTag(LayerItem::P_MATERIAL)) { - QVariant v = m_item->getItemValue(LayerItem::P_MATERIAL); - if (v.isValid()) { - ExternalProperty mp = v.value<ExternalProperty>(); - material = mp.text(); - } - } + if (LayerItem* item = dynamic_cast<LayerItem*>(m_item)) + material = item->material().text(); /* Thickness and roughness can be added, but the length of the string * becomes prohibitive. diff --git a/Tests/UnitTests/GUI/TestComponentUtils.cpp b/Tests/UnitTests/GUI/TestComponentUtils.cpp index 1cd6affef66..afa3d1de984 100644 --- a/Tests/UnitTests/GUI/TestComponentUtils.cpp +++ b/Tests/UnitTests/GUI/TestComponentUtils.cpp @@ -19,7 +19,7 @@ TEST_F(TestComponentUtils, test_componentItems) SessionItem* ffItem = particle->getGroupItem(ParticleItem::P_FORM_FACTOR); QList<const SessionItem*> expectedList = QList<const SessionItem*>() - << particle->getItem(ParticleItem::P_MATERIAL) + << particle->materialItem() << group << ffItem->getItem(CylinderItem::P_RADIUS) << ffItem->getItem(CylinderItem::P_HEIGHT) << particle->getItem(ParticleItem::P_ABUNDANCE) @@ -41,7 +41,7 @@ TEST_F(TestComponentUtils, test_componentItemsFFChange) SessionItem* sphereItem = particle->getGroupItem(ParticleItem::P_FORM_FACTOR); QList<const SessionItem*> expectedList = - QList<const SessionItem*>() << particle->getItem(ParticleItem::P_MATERIAL) + QList<const SessionItem*>() << particle->materialItem() << group << sphereItem->getItem(FullSphereItem::P_RADIUS) << particle->getItem(ParticleItem::P_ABUNDANCE) << particle->getItem(ParticleItem::P_POSITION); diff --git a/Tests/UnitTests/GUI/TestLayerItems.cpp b/Tests/UnitTests/GUI/TestLayerItems.cpp index b115c40a580..ee24f4d36c6 100644 --- a/Tests/UnitTests/GUI/TestLayerItems.cpp +++ b/Tests/UnitTests/GUI/TestLayerItems.cpp @@ -18,8 +18,7 @@ TEST_F(TestLayerItems, test_LayerDefaultMaterial) auto materials = models.materialModel()->topItems<MaterialItem>(); auto defMaterial = materials.front(); - ExternalProperty material = - layer->getItemValue(LayerItem::P_MATERIAL).value<ExternalProperty>(); + ExternalProperty material = layer->material(); EXPECT_EQ(material.text(), "Default"); EXPECT_EQ(material.identifier(), defMaterial->identifier()); } diff --git a/Tests/UnitTests/GUI/TestMaterialPropertyController.cpp b/Tests/UnitTests/GUI/TestMaterialPropertyController.cpp index 13a5f7c8f37..7e6a086c451 100644 --- a/Tests/UnitTests/GUI/TestMaterialPropertyController.cpp +++ b/Tests/UnitTests/GUI/TestMaterialPropertyController.cpp @@ -74,12 +74,9 @@ TEST_F(TestMaterialPropertyController, test_ControllerInEditorContext) MaterialPropertyController controller; controller.setModels(&materialModel, &sampleModel); - layer1->setItemValue(LayerItem::P_MATERIAL, - GUI::Model::MaterialItemUtils::materialProperty(*mat1).variant()); - layer2->setItemValue(LayerItem::P_MATERIAL, - GUI::Model::MaterialItemUtils::materialProperty(*mat2).variant()); - layer3->setItemValue(LayerItem::P_MATERIAL, - GUI::Model::MaterialItemUtils::materialProperty(*mat3).variant()); + layer1->setMaterial(GUI::Model::MaterialItemUtils::materialProperty(*mat1)); + layer2->setMaterial(GUI::Model::MaterialItemUtils::materialProperty(*mat2)); + layer3->setMaterial(GUI::Model::MaterialItemUtils::materialProperty(*mat3)); // Making copy of material model std::unique_ptr<MaterialModel> materialsCopy(materialModel.createCopy()); @@ -118,11 +115,10 @@ TEST_F(TestMaterialPropertyController, test_ControllerInEditorContext) materialModel.modelLoaded(); // layer2 should have undefined material property - ExternalProperty property = - layer2->getItemValue(LayerItem::P_MATERIAL).value<ExternalProperty>(); + ExternalProperty property = layer2->material(); EXPECT_FALSE(property.isValid()); // layer3 should have different MaterialProperty name - property = layer3->getItemValue(LayerItem::P_MATERIAL).value<ExternalProperty>(); + property = layer3->material(); EXPECT_EQ(property.text(), "name3changed"); } -- GitLab