Skip to content
Snippets Groups Projects
Commit a9e5a54d authored by Matthias Puchner's avatar Matthias Puchner
Browse files

add material-changed signaling to MaterialModel

parent d4deea01
No related branches found
No related tags found
1 merge request!420Layer editor improvements3
......@@ -90,6 +90,16 @@ QVector<MaterialItem*> MaterialModel::materialItems() const
return topItems<MaterialItem>();
}
MaterialItem* MaterialModel::findMaterialItem(const QString& identifier) const
{
for (auto* m : materialItems())
if (m->identifier() == identifier)
return m;
return nullptr;
}
void MaterialModel::removeMaterial(const QString& identifier)
{
removeMaterial(materialFromIdentifier(identifier));
......@@ -102,6 +112,55 @@ void MaterialModel::removeMaterial(MaterialItem* materialItem)
removeRows(index.row(), 1, index.parent());
}
void MaterialModel::readFrom(QXmlStreamReader* reader, MessageService* messageService /*= 0*/)
{
// do not send added-notifications until completely read - otherwise partially
// initialized items will be notified
disconnect(this, &SessionModel::rowsInserted, this, &MaterialModel::onRowsChange);
SessionModel::readFrom(reader, messageService);
connect(this, &SessionModel::rowsInserted, this, &MaterialModel::onRowsChange);
for (auto materialItem : materialItems()) {
materialItem->mapper()->setOnAnyChildChange(
[this, materialItem](SessionItem*) { materialChanged(materialItem); }, this);
}
}
void MaterialModel::initFrom(SessionModel* model, SessionItem* parent)
{
// since initFrom does not send materialChanged signals, this has to be done manually.
QStringList identifiersOfChangedMaterials;
auto* sourceModel = dynamic_cast<MaterialModel*>(model);
for (auto destItem : materialItems()) {
auto* srcItem = sourceModel->findMaterialItem(destItem->identifier());
if (srcItem && (*srcItem != *destItem))
identifiersOfChangedMaterials << destItem->identifier();
}
clear();
SessionModel::initFrom(model, parent);
for (auto identifier : identifiersOfChangedMaterials)
emit materialChanged(findMaterialItem(identifier));
}
void MaterialModel::onRowsChange(const QModelIndex& parent, int, int)
{
// valid parent means not a material (which is top level item) but something below
if (parent.isValid())
return;
for (auto materialItem : materialItems()) {
materialItem->mapper()->unsubscribe(this);
materialItem->mapper()->setOnAnyChildChange(
[this, materialItem](SessionItem*) { materialChanged(materialItem); }, this);
}
}
bool MaterialModel::operator!=(const MaterialModel& other) const
{
return !operator==(other);
......
......@@ -38,13 +38,23 @@ public:
MaterialItem* cloneMaterial(MaterialItem* material);
QVector<MaterialItem*> materialItems() const;
MaterialItem* findMaterialItem(const QString& identifier) const;
void removeMaterial(const QString& identifier);
void removeMaterial(MaterialItem* materialItem);
virtual void readFrom(QXmlStreamReader* reader, MessageService* messageService = 0) override;
virtual void initFrom(SessionModel* model, SessionItem* parent) override;
//! Compares for complete equality (same material identifiers, same order of materials,...)
bool operator==(const MaterialModel& other) const;
bool operator!=(const MaterialModel& other) const;
signals:
void materialChanged(MaterialItem* materialItem);
private:
void onRowsChange(const QModelIndex& parent, int, int);
};
#endif // BORNAGAIN_GUI_MODELS_MATERIALMODEL_H
......@@ -150,10 +150,9 @@ MaterialEditorDialog::~MaterialEditorDialog()
//! replaces original material model with the model modified by MaterialEditor
void MaterialEditorDialog::accept()
{
if (*m_document->materialModel() != *m_tmpMaterialModel) {
m_document->materialModel()->clear();
if (*m_document->materialModel() != *m_tmpMaterialModel)
m_document->materialModel()->initFrom(m_tmpMaterialModel.get(), 0);
}
QDialog::accept();
}
......
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