diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp index ed8715309b96de68f27179047862913df9a7e318..dfb57e9c846507cd9c45052f21d3e1fe24ea00f8 100644 --- a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp +++ b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp @@ -25,6 +25,7 @@ #include "RealDataItem.h" #include "SessionModel.h" #include "FitSuiteItem.h" +#include "PropertyRepeater.h" #include <QAction> #include <QGridLayout> #include <QLabel> @@ -44,6 +45,7 @@ FitComparisonWidget::FitComparisonWidget(QWidget *parent) , m_relativeDiffPlot(new ColorMapCanvas) , m_fitFlowWidget(new FitFlowWidget) , m_statusLabel(new ColorMapLabel(0, this)) + , m_repeater(new PropertyRepeater(this)) , m_relativeDiffItem(0) , m_resetViewAction(0) , m_tempIntensityDataModel(new SessionModel("TempIntensityDataModel")) @@ -111,6 +113,9 @@ void FitComparisonWidget::subscribeToItem() m_statusLabel->addColorMap(m_realDataPlot); m_statusLabel->addColorMap(m_simulatedDataPlot); m_statusLabel->addColorMap(m_relativeDiffPlot); + + m_repeater->addItem(realDataItem()); + m_repeater->addItem(simulatedDataItem()); } void FitComparisonWidget::unsubscribeFromItem() @@ -120,6 +125,8 @@ void FitComparisonWidget::unsubscribeFromItem() if (simulatedDataItem()) simulatedDataItem()->mapper()->unsubscribe(this); + + m_repeater->clear(); } void FitComparisonWidget::onResetViewAction() diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h index 206a596232cad30d9b687ece1082b3163e3f7b56..0538924812c7f54c78e791b1234df19e2ca2b48f 100644 --- a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h +++ b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h @@ -27,6 +27,7 @@ class SessionModel; class FitFlowWidget; class ColorMapLabel; class QAction; +class PropertyRepeater; //! The FitComparisonWidget class plots realdata, simulated data and relative difference map //! during the course of the fit. @@ -63,6 +64,7 @@ private: ColorMapCanvas* m_relativeDiffPlot; FitFlowWidget* m_fitFlowWidget; ColorMapLabel* m_statusLabel; + PropertyRepeater* m_repeater; IntensityDataItem* m_relativeDiffItem; QAction* m_resetViewAction; diff --git a/GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.cpp b/GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c2417b09ec71984fd546a5902588ad9a9b38012 --- /dev/null +++ b/GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.cpp @@ -0,0 +1,100 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.cpp +//! @brief Implements class PropertyRepeater +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2016 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors Céline Durniak, Marina Ganeva, David Li, Gennady Pospelov +//! @authors Walter Van Herck, Joachim Wuttke +// +// ************************************************************************** // + +#include "PropertyRepeater.h" +#include "IntensityDataItem.h" +#include <QDebug> + +PropertyRepeater::PropertyRepeater(QObject* parent) + : QObject(parent) + , m_block_repeater(false) +{ + +} + +void PropertyRepeater::addItem(IntensityDataItem* intensityItem) +{ + if (!intensityItem || m_dataItems.contains(intensityItem)) + return; + + + intensityItem->mapper()->setOnItemDestroy([this](SessionItem* item) + { + m_dataItems.removeAll(item); + }, this); + + intensityItem->mapper()->setOnPropertyChange( + [this](const QString& name) { onPropertyChanged(name); }, this); + + intensityItem->mapper()->setOnChildPropertyChange( + [this](SessionItem* item, const QString name) { + setOnChildPropertyChange(item, name); + }, this); + + + m_dataItems.push_back(intensityItem); +} + +void PropertyRepeater::clear() +{ + for (auto item : m_dataItems) + item->mapper()->unsubscribe(this); + + m_dataItems.clear(); +} + +void PropertyRepeater::onPropertyChanged(const QString& propertyName) +{ + if (m_block_repeater) + return; + + m_block_repeater = true; + + Q_UNUSED(propertyName); + + m_block_repeater = false; +} + +void PropertyRepeater::setOnChildPropertyChange(SessionItem* item, const QString& propertyName) +{ + if (m_block_repeater) + return; + + m_block_repeater = true; + + SessionItem* sourceItem = item->parent(); + QString tag = sourceItem->tagFromItem(item); + QVariant value = item->getItemValue(propertyName); + + qDebug() << "PropertyRepeater: " << item << item->modelType() << item->itemName() + << " parent:" << item->parent() << item->parent()->modelType() << item->parent()->itemName() + << " propertyName:" << propertyName; + qDebug() << "tag:" << tag << m_dataItems.size(); + + for (auto target : targetItems(sourceItem)) + target->getItem(tag)->setItemValue(propertyName, value); + + m_block_repeater = false; +} + +//! Returns list of target items to update their properties. + +QVector<SessionItem*> PropertyRepeater::targetItems(SessionItem* sourceItem) +{ + QVector<SessionItem*> result = m_dataItems; + result.removeAll(sourceItem); + return result; +} diff --git a/GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.h b/GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.h new file mode 100644 index 0000000000000000000000000000000000000000..8e7ccfd6e8ad0d30ef6bcb387032c38d78ecb350 --- /dev/null +++ b/GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.h @@ -0,0 +1,48 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file GUI/coregui/Views/IntensityDataWidgets/PropertyRepeater.h +//! @brief Defines class PropertyRepeater +//! +//! @homepage http://www.bornagainproject.org +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2016 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors Céline Durniak, Marina Ganeva, David Li, Gennady Pospelov +//! @authors Walter Van Herck, Joachim Wuttke +// +// ************************************************************************** // + +#ifndef PROPERTYREPEATER_H +#define PROPERTYREPEATER_H + +#include "WinDllMacros.h" +#include <QObject> +#include <QVector> + +class SessionItem; +class IntensityDataItem; + +//! Tracks property change (axes range, units etc) for the collection of IntensityDataItems +//! and sets same properties for all of them. + +class BA_CORE_API_ PropertyRepeater : public QObject +{ + Q_OBJECT +public: + explicit PropertyRepeater(QObject* parent = nullptr); + + void addItem(IntensityDataItem* item); + + void clear(); +private: + void onPropertyChanged(const QString& propertyName); + void setOnChildPropertyChange(SessionItem* item, const QString& propertyName); + QVector<SessionItem*> targetItems(SessionItem* sourceItem); + + QVector<SessionItem*> m_dataItems; + bool m_block_repeater; +}; + +#endif // PROPERTYREPEATER_H