From c78bb13f7b9d6704938ac761bf76f0279f8f3d9a Mon Sep 17 00:00:00 2001 From: David Li <dawei.li@gmx.net> Date: Mon, 21 Mar 2016 14:27:19 +0100 Subject: [PATCH] fix distributed particle --- GUI/coregui/Models/GroupProperty.cpp | 5 ++ GUI/coregui/Models/GroupProperty.h | 2 + GUI/coregui/Models/ModelMapper.cpp | 73 ++++++++++++++----- GUI/coregui/Models/ModelMapper.h | 7 ++ GUI/coregui/Models/ModelPath.cpp | 46 ++++++++---- .../Models/ParticleDistributionItem.cpp | 15 ++-- 6 files changed, 106 insertions(+), 42 deletions(-) diff --git a/GUI/coregui/Models/GroupProperty.cpp b/GUI/coregui/Models/GroupProperty.cpp index af65a88b89e..4ee9ca673a2 100644 --- a/GUI/coregui/Models/GroupProperty.cpp +++ b/GUI/coregui/Models/GroupProperty.cpp @@ -149,6 +149,11 @@ QString GroupProperty::toString(int index) const return name_list[index]; } +bool GroupProperty::isFixed() const +{ + return m_group_type == GroupProperty::FIXED; +} + void GroupProperty::setGroupMap(std::map<QString, QString> group_map) { m_type_label_map = std::move(group_map); diff --git a/GUI/coregui/Models/GroupProperty.h b/GUI/coregui/Models/GroupProperty.h index 7d9245cb7cc..5a09a01873f 100644 --- a/GUI/coregui/Models/GroupProperty.h +++ b/GUI/coregui/Models/GroupProperty.h @@ -57,6 +57,8 @@ public: int toIndex(const QString &type) const; QString toString(int index) const; + bool isFixed() const; + friend class GroupPropertyRegistry; private: GroupProperty(QString group_name); diff --git a/GUI/coregui/Models/ModelMapper.cpp b/GUI/coregui/Models/ModelMapper.cpp index d35f291be5a..8a11e5d8517 100644 --- a/GUI/coregui/Models/ModelMapper.cpp +++ b/GUI/coregui/Models/ModelMapper.cpp @@ -65,6 +65,11 @@ void ModelMapper::setOnSiblingsChange(std::function<void ()> f) m_onSiblingsChange.push_back(f); } +void ModelMapper::setOnAnyChildChange(std::function<void (SessionItem *)> f) +{ + m_onAnyChildChange.push_back(f); +} + void ModelMapper::setModel(SessionModel *model) { if (m_model) { @@ -74,6 +79,8 @@ void ModelMapper::setModel(SessionModel *model) this, SLOT(onRowsInserted(QModelIndex,int,int))); disconnect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(onBeginRemoveRows(QModelIndex,int,int))); + disconnect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(onRowRemoved(QModelIndex,int,int))); } if (model) { m_model = model; @@ -83,6 +90,8 @@ void ModelMapper::setModel(SessionModel *model) this, SLOT(onRowsInserted(QModelIndex,int,int))); connect(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)), this, SLOT(onBeginRemoveRows(QModelIndex,int,int))); + connect(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int)), + this, SLOT(onRowRemoved(QModelIndex,int,int))); } } @@ -150,6 +159,15 @@ void ModelMapper::callOnSiblingsChange() } } +void ModelMapper::callOnAnyChildChange(SessionItem *item) +{ + if (m_active && m_onAnyChildChange.size() > 0) { + for (auto f : m_onAnyChildChange) { + f(item); + } + } +} + void ModelMapper::onDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &/*roles*/) { @@ -180,20 +198,25 @@ void ModelMapper::onDataChanged(const QModelIndex &topLeft, const QModelIndex &b } } } + if (nestling > 0) { + callOnAnyChildChange(item); + } } -void ModelMapper::onRowsInserted(const QModelIndex &parent, int first, int last) +void ModelMapper::onRowsInserted(const QModelIndex &parent, int first, int /*last*/) { - if(!parent.isValid()) return; + SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0)); - if (SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0))) { + int nestling = nestlingDepth(newChild); + + if (newChild) { if (m_item == newChild) { callOnParentChange(m_model->itemForIndex(parent)); } + } + if (nestling == 1) { - else if(m_item == newChild->parent()) { - callOnChildrenChange(); - } + callOnChildrenChange(); // inform siblings about the change // FIXME SessionItems with invalid parent index (i.e. IView's located on top of graphics scene like ParticleView) should be also notified to update the label @@ -204,34 +227,46 @@ void ModelMapper::onRowsInserted(const QModelIndex &parent, int first, int last) if(m_item == sibling) callOnSiblingsChange(); } } + } + if (nestling > 0) { + callOnAnyChildChange(newChild); } } -void ModelMapper::onBeginRemoveRows(const QModelIndex &parent, int first, int last) +void ModelMapper::onBeginRemoveRows(const QModelIndex &parent, int first, int /*last*/) { - if(!parent.isValid()) return; + SessionItem *oldChild = m_model->itemForIndex(parent.child(first, 0)); - if (SessionItem *newChild = m_model->itemForIndex(parent.child(first, 0))) { - if (m_item == newChild) { - callOnParentChange(nullptr); + int nestling = nestlingDepth(m_model->itemForIndex(parent)); + + if (oldChild) { + if (m_item == oldChild) { + callOnParentChange(m_model->itemForIndex(parent)); } + if (nestling == 0) { - else if(m_item == newChild->parent()) { callOnChildrenChange(); - } - // inform siblings about the change - if(SessionItem *parent = newChild->parent()) { -// QVector<SessionItem *> items = parent->getItems(parent->tagFromItem(newChild)); - QVector<SessionItem *> items = parent->getChildrenOfType(newChild->modelType()); - foreach(SessionItem *sibling, items) { - if(m_item == sibling) callOnSiblingsChange(); + // inform siblings about the change + if(SessionItem *parent = oldChild->parent()) { + // QVector<SessionItem *> items = parent->getItems(parent->tagFromItem(newChild)); + QVector<SessionItem *> items = parent->getChildrenOfType(oldChild->modelType()); + foreach(SessionItem *sibling, items) { + if(m_item == sibling) callOnSiblingsChange(); + } } } + } +} +void ModelMapper::onRowRemoved(const QModelIndex &parent, int /*first*/, int /*last*/) +{ + int nestling = nestlingDepth(m_model->itemForIndex(parent)); + if (nestling >= 0 || m_model->itemForIndex(parent) == m_item->parent()) { + callOnAnyChildChange(nullptr); } } diff --git a/GUI/coregui/Models/ModelMapper.h b/GUI/coregui/Models/ModelMapper.h index 76fffb2f7d6..3612fe7da6a 100644 --- a/GUI/coregui/Models/ModelMapper.h +++ b/GUI/coregui/Models/ModelMapper.h @@ -47,6 +47,8 @@ public: void setOnSiblingsChange(std::function<void(void)> f); + void setOnAnyChildChange(std::function<void(SessionItem*)> f); + void setActive(bool state) {m_active = state;} public slots: @@ -57,6 +59,8 @@ public slots: void onBeginRemoveRows(const QModelIndex & parent, int first, int last); + void onRowRemoved(const QModelIndex & parent, int first, int last); + private: void setModel(SessionModel *model); int nestlingDepth(SessionItem* item, int level = 0); @@ -67,6 +71,8 @@ private: void callOnParentChange(SessionItem *new_parent); void callOnChildrenChange(); void callOnSiblingsChange(); + void callOnAnyChildChange(SessionItem *item); + bool m_active; SessionModel *m_model; @@ -77,6 +83,7 @@ private: std::vector<std::function<void(SessionItem*)>> m_onParentChange; std::vector<std::function<void(void)>> m_onChildrenChange; std::vector<std::function<void(void)>> m_onSiblingsChange; + std::vector<std::function<void(SessionItem*)>> m_onAnyChildChange; }; #endif diff --git a/GUI/coregui/Models/ModelPath.cpp b/GUI/coregui/Models/ModelPath.cpp index 70cf5363818..1b966d0fca0 100644 --- a/GUI/coregui/Models/ModelPath.cpp +++ b/GUI/coregui/Models/ModelPath.cpp @@ -17,6 +17,7 @@ #include "SessionItem.h" #include "GroupProperty.h" #include "GroupItem.h" +#include "ParticleItem.h" #include <QModelIndex> #include <QStringList> #include <sstream> @@ -28,26 +29,32 @@ QStringList ModelPath::getParameterTreeList(const SessionItem *item, QString pre { QStringList result; if (item->modelType() == Constants::PropertyType - && item->value().type() == QVariant::Double) { + && item->value().type() == QVariant::Double && item->itemName() != ParticleItem::P_ABUNDANCE) { + if (prefix.endsWith("/")) + prefix = prefix.mid(0, prefix.size()-1); result << prefix; } - -// else if (item->modelType() == Constants::GroupItemType) { -// if (const GroupItem *groupItem = dynamic_cast<const GroupItem*>(item)) { -// if (const SessionItem *subItem = groupItem->group()->getCurrentItem()) { -// QString child_prefix = prefix + subItem->itemName() + QString("/"); -// result << getParameterTreeList(subItem, child_prefix); -// } -// } -// } - else { if (item->hasChildren()) { for (auto p_child : item->childItems()) { if(p_child->isVisible()) { - QString child_name = p_child->itemName(); - QString child_prefix = prefix + child_name + QString("/"); - result << getParameterTreeList(p_child, child_prefix); + if (p_child->modelType() == Constants::GroupItemType) { + if (const GroupItem *groupItem = dynamic_cast<const GroupItem*>(p_child)) { + if (const SessionItem *subItem = groupItem->group()->getCurrentItem()) { + if (groupItem->group()->isFixed()) { + QString child_prefix = prefix + groupItem->itemName() + QString("/"); + result << getParameterTreeList(subItem, child_prefix); + } else { + QString child_prefix = prefix + subItem->itemName() + QString("/"); + result << getParameterTreeList(subItem, child_prefix); + } + } + } + } else { + QString child_name = p_child->itemName(); + QString child_prefix = prefix + child_name + QString("/"); + result << getParameterTreeList(p_child, child_prefix); + } } } } @@ -81,6 +88,17 @@ std::string ModelPath::translateParameterName(const SessionItem *item, const QSt if (list.size() > 1) { auto remainder = list[1]; auto p_child = item->getChildByName(first_field); + if (!p_child) { //search through group items + auto groupItems = item->getChildrenOfType(Constants::GroupItemType); + for (auto groupItem : groupItems) { + if (GroupItem *gItem = dynamic_cast<GroupItem*>(groupItem)) { + if (gItem->group()->getCurrentType() == first_field) { + p_child = gItem->group()->getCurrentItem(); + break; + } + } + } + } if (p_child) { result << translateParameterName(p_child, remainder); } diff --git a/GUI/coregui/Models/ParticleDistributionItem.cpp b/GUI/coregui/Models/ParticleDistributionItem.cpp index b5a90c141b3..11bee691a8d 100644 --- a/GUI/coregui/Models/ParticleDistributionItem.cpp +++ b/GUI/coregui/Models/ParticleDistributionItem.cpp @@ -50,15 +50,12 @@ ParticleDistributionItem::ParticleDistributionItem() ComboProperty par_prop; addProperty(P_DISTRIBUTED_PARAMETER, par_prop.getVariant()); updateParameterList(); - mapper()->setOnChildPropertyChange( - [this](SessionItem*,QString) - { - updateParameterList(); - }); - - mapper()->setOnChildrenChange( - [this]() + mapper()->setOnAnyChildChange( + [this] (SessionItem* item) { + // prevent infinit loop when item changes its own properties + if (item && item->modelType()== Constants::PropertyType && item->parent() == this) + return; updateParameterList(); }); @@ -74,7 +71,7 @@ std::unique_ptr<ParticleDistribution> ParticleDistributionItem::createParticleDi if (children.size() == 0) { return nullptr; } - std::unique_ptr<IParticle> P_particle = TransformToDomain::createIParticle(*children[0]); + std::unique_ptr<IParticle> P_particle = TransformToDomain::createIParticle(*getItem()); if (!P_particle) { throw GUIHelpers::Error("DomainObjectBuilder::buildParticleDistribution()" " -> Error! No correct particle defined"); -- GitLab