// ************************************************************************************************ // // BornAgain: simulate and fit reflection and scattering // //! @file GUI/Model/Job/ParameterTreeUtils.cpp //! @brief Implements ParameterTreeUtils namespace //! //! @homepage http://www.bornagainproject.org //! @license GNU General Public License v3 or higher (see COPYING) //! @copyright Forschungszentrum Jülich GmbH 2018 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) // // ************************************************************************************************ #include "GUI/Model/Job/ParameterTreeUtils.h" #include "GUI/Model/Fit/ParameterTreeItems.h" #include "GUI/Model/Group/GroupItem.h" #include "GUI/Model/Group/PropertyItem.h" #include "GUI/Model/Instrument/InstrumentItems.h" #include "GUI/Model/Job/JobItem.h" #include "GUI/Model/Session/ModelPath.h" #include "GUI/Model/Material/MaterialItemContainer.h" #include "GUI/Model/Sample/MultiLayerItem.h" #include "GUI/Util/Error.h" #include <QStack> #include <boost/polymorphic_cast.hpp> using boost::polymorphic_downcast; namespace { void handleItem(SessionItem* tree, const SessionItem* source) { if (tree->hasModelType<ParameterLabelItem>()) tree->setDisplayName(source->itemName()); else if (tree->hasModelType<ParameterItem>()) { tree->setDisplayName(source->itemName()); double sourceValue = source->value().toDouble(); tree->setValue(QVariant(sourceValue)); QString path = GUI::Model::Path::getPathFromIndex(source->index()); int firstSlash = path.indexOf('/'); path = path.mid(firstSlash + 1); auto* parItem = polymorphic_downcast<ParameterItem*>(tree); parItem->setLink(path); parItem->setBackup(sourceValue); return; } else return; for (SessionItem* child : source->children()) { if (child->isVisible() && child->isEnabled()) { if (child->hasModelType<PropertyItem>()) { if (child->value().type() == QVariant::Double) { auto* branch = tree->model()->insertItem<ParameterItem>(tree); handleItem(branch, child); } } else if (child->hasModelType<GroupItem>()) { SessionItem* currentItem = dynamic_cast<GroupItem*>(child)->currentItem(); if (currentItem && currentItem->numberOfChildren() > 0) { auto* branch = tree->model()->insertItem<ParameterLabelItem>(tree); handleItem(branch, currentItem); } } else { auto* branch = tree->model()->insertItem<ParameterLabelItem>(tree); handleItem(branch, child); } } } } //! Populates ParameterContainer with ParameterItem's corresponding to all properties found //! in a source item. void populateParameterContainer(SessionItem* container, const SessionItem* source) { if (!container->hasModelType<ParameterContainerItem>()) throw Error("GUI::Model::ParameterTreeUtils::populateParameterContainer() -> Error. " "Not a ParameterContainerType."); auto* sourceLabel = container->model()->insertItem<ParameterLabelItem>(container); handleItem(sourceLabel, source); } } // namespace void GUI::Model::ParameterTreeUtils::createParameterTree(JobItem* jobItem) { auto* container = jobItem->parameterContainerItem(); if (!container) container = jobItem->createParameterContainerItem(); populateParameterContainer(container, jobItem->materialContainerItem()); populateParameterContainer(container, jobItem->sampleItem()); populateParameterContainer(container, jobItem->instrumentItem()); }