diff --git a/GUI/Models/ItemWithMaterial.cpp b/GUI/Models/ItemWithMaterial.cpp index 8560a19bb54cdded7abf622514066fa8ebb53066..982f7aa87755c90b5506d5e1f4e6cb855bce8992 100644 --- a/GUI/Models/ItemWithMaterial.cpp +++ b/GUI/Models/ItemWithMaterial.cpp @@ -31,11 +31,6 @@ bool ItemWithMaterial::isMaterialPropertyName(const QString& name) return name == P_MATERIAL; } -SessionItem* ItemWithMaterial::materialItem() const -{ - return getItem(P_MATERIAL); -} - void ItemWithMaterial::setMaterialUndefined() { setItemValue(P_MATERIAL, QString()); diff --git a/GUI/Models/ItemWithMaterial.h b/GUI/Models/ItemWithMaterial.h index 76d9f201c8d8eb5dae7258348047f4384125b150..db74fd990b6ebeb06a902b5e0f305f9ebe655900 100644 --- a/GUI/Models/ItemWithMaterial.h +++ b/GUI/Models/ItemWithMaterial.h @@ -26,10 +26,6 @@ private: public: static bool isMaterialPropertyName(const QString& name); - //! Returns the item which stores the link to the material. - //! Does not return the "MaterialItem"! - SessionItem* materialItem() const; - //! Set the material this item shall use. Stores the identifier, not the pointer! void setMaterial(const MaterialItem* materialItem); diff --git a/GUI/Models/JobModelFunctions.cpp b/GUI/Models/JobModelFunctions.cpp index 080fe64ab987d7af4450a5447ad9a127c97f531f..896cff85b7c57306d78292897a3eb1230dfc98fe 100644 --- a/GUI/Models/JobModelFunctions.cpp +++ b/GUI/Models/JobModelFunctions.cpp @@ -24,6 +24,7 @@ #include "GUI/Models/InstrumentItems.h" #include "GUI/Models/IntensityDataItem.h" #include "GUI/Models/ItemFileNameUtils.h" +#include "GUI/Models/ItemWithMaterial.h" #include "GUI/Models/JobItem.h" #include "GUI/Models/JobItemUtils.h" #include "GUI/Models/MaterialItemContainer.h" @@ -132,18 +133,18 @@ void GUI::Model::JobFunctions::setupJobItemSampleData(JobItem* jobItem, // copying materials MaterialItemContainer* container = jobItem->createMaterialContainer(); - std::map<MaterialItem*, QString> materials; - for (auto property_item : multilayer->materialPropertyItems()) { - auto materialIdentifier = property_item->value().toString(); + std::map<MaterialItem*, MaterialItem*> materials; + for (auto* itemWithMaterial : multilayer->itemsWithMaterial()) { + auto materialIdentifier = itemWithMaterial->materialIdentifier(); auto material = GUI::Model::MaterialItemUtils::findMaterial(materialIdentifier); auto iter = materials.find(material); if (iter == materials.end()) { - auto material_copy = container->insertCopy(material); - materials.insert({material, material_copy->identifier()}); - property_item->setValue(material_copy->identifier()); + auto materialCopy = container->insertCopy(material); + materials[material] = materialCopy; + itemWithMaterial->setMaterial(materialCopy); } else - property_item->setValue(iter->second); + itemWithMaterial->setMaterial(iter->second); } } diff --git a/GUI/Models/LayerItem.cpp b/GUI/Models/LayerItem.cpp index cef0583bc53be7d717c987e54eceff72c1f9049d..cfeb699d2995e79a7c6ec84d5736e96848059ee3 100644 --- a/GUI/Models/LayerItem.cpp +++ b/GUI/Models/LayerItem.cpp @@ -55,13 +55,12 @@ LayerItem::LayerItem() : SessionGraphicsItem(M_TYPE), ItemWithMaterial(M_TYPE) mapper()->setOnParentChange([this](SessionItem* new_parent) { updateAppearance(new_parent); }); } -QVector<SessionItem*> LayerItem::materialPropertyItems() +QVector<ItemWithMaterial*> LayerItem::itemsWithMaterial() { - QVector<SessionItem*> result; - if (auto property = materialItem()) - result.push_back(property); - for (auto layout : getItems(LayerItem::T_LAYOUTS)) - result.append(GUI::Model::MaterialItemUtils::materialPropertyItems(layout)); + QVector<ItemWithMaterial*> result; + result.push_back(this); + for (auto layout : layouts()) + result.append(GUI::Model::MaterialItemUtils::itemsWithMaterial(layout)); return result; } diff --git a/GUI/Models/LayerItem.h b/GUI/Models/LayerItem.h index de70145c62a73b8d1a8a82f38f0c709c41572aa6..dc0ef50079389adcd5c418c5d1816de63a19af28 100644 --- a/GUI/Models/LayerItem.h +++ b/GUI/Models/LayerItem.h @@ -33,7 +33,7 @@ public: LayerItem(); - QVector<SessionItem*> materialPropertyItems(); + QVector<ItemWithMaterial*> itemsWithMaterial(); double thickness() const; void setThickness(double thickness); diff --git a/GUI/Models/MaterialItemUtils.cpp b/GUI/Models/MaterialItemUtils.cpp index 2c57a478972d00c305adec9f8409450d22a6ce78..b1170098605b94749705c3ff09ea92adfa59044b 100644 --- a/GUI/Models/MaterialItemUtils.cpp +++ b/GUI/Models/MaterialItemUtils.cpp @@ -99,41 +99,34 @@ MaterialItem* GUI::Model::MaterialItemUtils::findMaterial(const QString& materia return material; } -//! Returns list of model types which contains registered MaterialProperty. - -QStringList GUI::Model::MaterialItemUtils::materialRelatedModelTypes() +QVector<ItemWithMaterial*> +GUI::Model::MaterialItemUtils::itemsWithMaterial(ParticleLayoutItem* item) { - return {ParticleItem::M_TYPE, LayerItem::M_TYPE}; -} + QVector<ItemWithMaterial*> itemsWithMaterial; -QVector<SessionItem*> GUI::Model::MaterialItemUtils::materialPropertyItems(SessionItem* item) -{ - QVector<SessionItem*> materials; - std::deque<SessionItem*> particle_holders{item}; - while (!particle_holders.empty()) { - SessionItem* item = particle_holders.front(); - particle_holders.pop_front(); + QVector<ItemWithParticles*> itemsWithParticles{dynamic_cast<ItemWithParticles*>(item)}; + while (!itemsWithParticles.empty()) { + auto* item = itemsWithParticles.takeFirst(); if (!item) continue; - if (item->hasModelType<ParticleCompositionItem>()) { - QVector<ItemWithParticles*> particles = - polymorphic_cast<ParticleCompositionItem*>(item)->particles(); - particle_holders.insert(particle_holders.end(), particles.begin(), particles.end()); - } else if (item->hasModelType<ParticleLayoutItem>()) { - QVector<ItemWithParticles*> particles = - polymorphic_cast<ParticleLayoutItem*>(item)->particles(); - particle_holders.insert(particle_holders.end(), particles.begin(), particles.end()); - } else if (item->hasModelType<MesoCrystalItem>()) - particle_holders.push_back(polymorphic_cast<MesoCrystalItem*>(item)->basisParticle()); + if (item->hasModelType<ParticleCompositionItem>()) + itemsWithParticles << polymorphic_cast<ParticleCompositionItem*>(item)->particles(); + else if (item->hasModelType<ParticleLayoutItem>()) + itemsWithParticles << polymorphic_cast<ParticleLayoutItem*>(item)->particles(); + else if (item->hasModelType<MesoCrystalItem>()) + itemsWithParticles << polymorphic_cast<MesoCrystalItem*>(item)->basisParticle(); else if (item->hasModelType<ParticleItem>()) - materials.append(dynamic_cast<ParticleItem*>(item)->materialPropertyItems()); - else if (item->hasModelType<ParticleCoreShellItem>()) - materials.append(dynamic_cast<ParticleCoreShellItem*>(item)->materialPropertyItems()); - else + itemsWithMaterial << dynamic_cast<ParticleItem*>(item); + else if (item->hasModelType<ParticleCoreShellItem>()) { + if (auto core = dynamic_cast<ParticleCoreShellItem*>(item)->core()) + itemsWithMaterial << core; + if (auto shell = dynamic_cast<ParticleCoreShellItem*>(item)->shell()) + itemsWithMaterial << shell; + } else throw Error("Error in GUI::Model::MaterialItemUtils::materialProperties: cannot handle " "passed model type '" + item->modelType() + "'"); } - return materials; + return itemsWithMaterial; } diff --git a/GUI/Models/MaterialItemUtils.h b/GUI/Models/MaterialItemUtils.h index 71644cbf888ed8bc9f0f21ce64af9a439f8785c4..98c93d2d63df636feb24fd221c0a8cd7f03b17ba 100644 --- a/GUI/Models/MaterialItemUtils.h +++ b/GUI/Models/MaterialItemUtils.h @@ -22,6 +22,8 @@ class Material; class MaterialItemContainer; +class ItemWithMaterial; +class ParticleLayoutItem; namespace GUI::Model::MaterialItemUtils { @@ -36,10 +38,8 @@ std::unique_ptr<Material> createDomainMaterial(const QString& materialIdentifier MaterialItem* findMaterial(const QString& materialIdentifier); -QStringList materialRelatedModelTypes(); - //! Gather material property items from a given item -QVector<SessionItem*> materialPropertyItems(SessionItem* item); +QVector<ItemWithMaterial*> itemsWithMaterial(ParticleLayoutItem* item); } // namespace GUI::Model::MaterialItemUtils diff --git a/GUI/Models/MultiLayerItem.cpp b/GUI/Models/MultiLayerItem.cpp index 23eb183be212231c7187fdf5a5b7132b2f81d7db..034bb9a469ed54672f37ffbe4f52ca9c3af9139c 100644 --- a/GUI/Models/MultiLayerItem.cpp +++ b/GUI/Models/MultiLayerItem.cpp @@ -44,11 +44,11 @@ MultiLayerItem::MultiLayerItem() : SessionGraphicsItem(M_TYPE) mapper()->setOnChildrenChange([this](SessionItem*) { updateLayers(); }); } -QVector<SessionItem*> MultiLayerItem::materialPropertyItems() +QVector<ItemWithMaterial*> MultiLayerItem::itemsWithMaterial() { - QVector<SessionItem*> result; + QVector<ItemWithMaterial*> result; for (auto layer_item : getItems(T_LAYERS)) - result.append(dynamic_cast<LayerItem*>(layer_item)->materialPropertyItems()); + result.append(dynamic_cast<LayerItem*>(layer_item)->itemsWithMaterial()); return result; } diff --git a/GUI/Models/MultiLayerItem.h b/GUI/Models/MultiLayerItem.h index 4952dc263fb8f44b2872d1235b029cc663b77c97..24a7f41dec4d2f58ca255c90cb869d8a336be096 100644 --- a/GUI/Models/MultiLayerItem.h +++ b/GUI/Models/MultiLayerItem.h @@ -19,6 +19,7 @@ #include "GUI/Models/SessionGraphicsItem.h" class LayerItem; +class ItemWithMaterial; class BA_CORE_API_ MultiLayerItem : public SessionGraphicsItem { private: @@ -31,7 +32,7 @@ public: MultiLayerItem(); - QVector<SessionItem*> materialPropertyItems(); + QVector<ItemWithMaterial*> itemsWithMaterial(); double crossCorrLength() const; void setCrossCorrLength(double cross_corr_length); diff --git a/GUI/Models/ParticleCoreShellItem.cpp b/GUI/Models/ParticleCoreShellItem.cpp index ae4b2e283786b2f13521bbaa8ed6c4d5f254a8a8..d1e48c181b44b7c932192ab4c84e103efbe4649a 100644 --- a/GUI/Models/ParticleCoreShellItem.cpp +++ b/GUI/Models/ParticleCoreShellItem.cpp @@ -65,18 +65,6 @@ std::unique_ptr<ParticleCoreShell> ParticleCoreShellItem::createParticleCoreShel return P_coreshell; } -QVector<SessionItem*> ParticleCoreShellItem::materialPropertyItems() -{ - QVector<SessionItem*> result; - if (auto core = dynamic_cast<ParticleItem*>(getItem(T_CORE))) - result.append(core->materialPropertyItems()); - - if (auto shell = dynamic_cast<ParticleItem*>(getItem(T_SHELL))) - result.append(shell->materialPropertyItems()); - - return result; -} - ParticleItem* ParticleCoreShellItem::core() const { return dynamic_cast<ParticleItem*>(getItem(T_CORE)); diff --git a/GUI/Models/ParticleCoreShellItem.h b/GUI/Models/ParticleCoreShellItem.h index c2bc7ffaa568862438ef5c9405e23a71c8750f11..d3b68d1d15a0ab331251f9e91dd3e6e38dba8616 100644 --- a/GUI/Models/ParticleCoreShellItem.h +++ b/GUI/Models/ParticleCoreShellItem.h @@ -32,7 +32,6 @@ public: ParticleCoreShellItem(); std::unique_ptr<ParticleCoreShell> createParticleCoreShell() const; - QVector<SessionItem*> materialPropertyItems(); ParticleItem* core() const; void setCore(ParticleItem* core); diff --git a/GUI/Models/ParticleItem.cpp b/GUI/Models/ParticleItem.cpp index 05b376c283c733e360ced9e9ea97bc2fedad34f7..32ad832034f6ada5ed2be8b1c328a0473779410f 100644 --- a/GUI/Models/ParticleItem.cpp +++ b/GUI/Models/ParticleItem.cpp @@ -61,14 +61,6 @@ std::unique_ptr<Particle> ParticleItem::createParticle() const return particle; } -QVector<SessionItem*> ParticleItem::materialPropertyItems() -{ - auto item = materialItem(); - if (!item) - return {}; - return {item}; -} - SessionItem* ParticleItem::setFormFactor(const QString& model_type) { return setGroupProperty(P_FORM_FACTOR, model_type); diff --git a/GUI/Models/ParticleItem.h b/GUI/Models/ParticleItem.h index 9b177d6c6509c8b545fb2cc6f34a4f39823b52fa..0ed2fd52b5f14fd47b23fe6eb93d69eeebc24b2c 100644 --- a/GUI/Models/ParticleItem.h +++ b/GUI/Models/ParticleItem.h @@ -33,7 +33,6 @@ public: ParticleItem(); std::unique_ptr<Particle> createParticle() const; - QVector<SessionItem*> materialPropertyItems(); template <typename T> T* setFormFactorType(); SessionItem* setFormFactor(const QString& model_type); diff --git a/GUI/Models/SampleModel.cpp b/GUI/Models/SampleModel.cpp index 3eb9582471678542fdf30217d9365a4f97840686..50340ccb5b6959e829117e38aa21aa4c2e4bf549 100644 --- a/GUI/Models/SampleModel.cpp +++ b/GUI/Models/SampleModel.cpp @@ -69,18 +69,10 @@ MultiLayerItem* SampleModel::multiLayerItem() QVector<ItemWithMaterial*> SampleModel::itemsWithMaterial() const { - static const QStringList materialRelated = - GUI::Model::MaterialItemUtils::materialRelatedModelTypes(); - QVector<ItemWithMaterial*> result; - GUI::Model::ItemUtils::iterate(QModelIndex(), this, [&](const QModelIndex& index) { - if (index.column() != 0) - return; - if (SessionItem* item = itemForIndex(index)) - if (materialRelated.contains(item->modelType())) - result.push_back(polymorphic_cast<ItemWithMaterial*>(item)); - }); + for (auto* m : topItems<MultiLayerItem>()) + result << m->itemsWithMaterial(); return result; } diff --git a/Tests/Unit/GUI/TestComponentUtils.cpp b/Tests/Unit/GUI/TestComponentUtils.cpp index 673e709015f43d7beb7d6320e01ab430481e44c4..e9d0af5b025ab77a4dd96e59a809429d57289611 100644 --- a/Tests/Unit/GUI/TestComponentUtils.cpp +++ b/Tests/Unit/GUI/TestComponentUtils.cpp @@ -22,14 +22,14 @@ TEST_F(TestComponentUtils, test_componentItems) CylinderItem* ffCylinder = dynamic_cast<CylinderItem*>(ffItem); EXPECT_NE(ffCylinder, nullptr); - QList<const SessionItem*> expectedList = - QList<const SessionItem*>() - << particle->materialItem() << particle->abundanceItem() << particle->positionItem() - << group << ffCylinder->radiusItem() << ffCylinder->heightItem(); - auto itemList = GUI::Model::ComponentUtils::componentItems(*particle); EXPECT_EQ(itemList.size(), 6); - EXPECT_EQ(itemList, expectedList); + EXPECT_TRUE(itemList.contains(particle->abundanceItem())); + EXPECT_TRUE(itemList.contains(particle->positionItem())); + EXPECT_TRUE(itemList.contains(group)); + EXPECT_TRUE(itemList.contains(ffCylinder->radiusItem())); + EXPECT_TRUE(itemList.contains(ffCylinder->heightItem())); + // the 6th is material item (holds material identifier) } TEST_F(TestComponentUtils, test_componentItemsFFChange) @@ -42,12 +42,11 @@ TEST_F(TestComponentUtils, test_componentItemsFFChange) particle->setFormFactorType<FullSphereItem>(); FullSphereItem* sphereItem = dynamic_cast<FullSphereItem*>(particle->formFactor()); - QList<const SessionItem*> expectedList = - QList<const SessionItem*>() - << particle->materialItem() << particle->abundanceItem() << particle->positionItem() - << group << sphereItem->radiusItem(); - auto itemList = GUI::Model::ComponentUtils::componentItems(*particle); EXPECT_EQ(itemList.size(), 5); - EXPECT_EQ(itemList, expectedList); + EXPECT_TRUE(itemList.contains(particle->abundanceItem())); + EXPECT_TRUE(itemList.contains(particle->positionItem())); + EXPECT_TRUE(itemList.contains(group)); + EXPECT_TRUE(itemList.contains(sphereItem->radiusItem())); + // the 5th is material item (holds material identifier) }