/*========================================================================= medInria Copyright (c) INRIA 2013 - 2018. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #include "medCompositeParameterL.h" #include #include #include class medCompositeParameterLPrivate { public: QHash variants; QHash > ranges; QHash steps; QHash widgets; ~medCompositeParameterLPrivate() { variants.clear(); QHashIterator i(widgets); while (i.hasNext()) { i.next(); delete i.value(); } widgets.clear(); } }; medCompositeParameterL::medCompositeParameterL(QString name, QObject* parent): medAbstractParameterL(name, parent), d(new medCompositeParameterLPrivate) { } medCompositeParameterL::~medCompositeParameterL() { delete d; } QWidget* medCompositeParameterL::getWidget() { QWidget *mainWidget = new QWidget; QFormLayout *layout = new QFormLayout(mainWidget); QHash::const_iterator i = d->widgets.constBegin(); while (i != d->widgets.constEnd()) { layout->addRow(i.key(), i.value()); ++i; } return mainWidget; } void medCompositeParameterL::setValues(const QHash value) { QHash::const_iterator valuesIterator = value.constBegin(); bool valueUpdated = false; while (valuesIterator != value.constEnd()) { QString key = valuesIterator.key(); if (!d->variants.contains(key)) { valuesIterator++; continue; } if(d->variants[key].type() == QVariant::Double) { double previousValue = d->variants[key].toDouble(); if(valuesIterator.value().toDouble() < d->ranges.value(key).first.toDouble()) d->variants[key] = d->ranges.value(key).first; else if(valuesIterator.value().toDouble() > d->ranges.value(key).second.toDouble()) d->variants[key] = d->ranges.value(key).second; else d->variants[key] = valuesIterator.value(); if( previousValue != d->variants[key] ) valueUpdated = true; } else if(d->variants[key].type() == QVariant::Int) { int previousValue = d->variants[key].toInt(); if(valuesIterator.value().toInt() < d->ranges.value(key).first.toInt()) d->variants[key] = d->ranges.value(key).first; else if(valuesIterator.value().toInt() > d->ranges.value(key).second.toInt()) d->variants[key] = d->ranges.value(key).second; else d->variants[key] = valuesIterator.value(); if( previousValue != d->variants[key] ) valueUpdated = true; } else { if (!( d->variants[key] == valuesIterator.value())) { d->variants[key] = valuesIterator.value(); valueUpdated = true; } } valuesIterator++; } if(!valueUpdated) return; // update intern widget this->blockInternWidgetsSignals(true); this->updateInternWigets(); this->blockInternWidgetsSignals(false); emit valuesChanged(d->variants); } QList medCompositeParameterL::values() const { return d->variants.values(); } QVariant medCompositeParameterL::value(const QString key) const { return d->variants[key]; } void medCompositeParameterL::updateInternWigets() { QHash::const_iterator i = d->variants.constBegin(); while (i != d->variants.constEnd()) { QString name = i.key(); QVariant var = i.value(); QWidget* widget = d->widgets.value(name); if(QCheckBox *checkbox = qobject_cast(widget)) checkbox->setChecked(var.toBool()); else if(QSpinBox *spinBox = qobject_cast(widget)) spinBox->setValue(var.toInt()); else if(QDoubleSpinBox *doubleSpinBox = qobject_cast(widget)) doubleSpinBox->setValue(var.toDouble()); ++i; } } void medCompositeParameterL::addVariant(QString name, QVariant variant, QVariant min, QVariant max, QVariant step) { d->variants.insert(name, variant); if(variant.type() == QVariant::Bool) { QCheckBox *checkbox = new QCheckBox(name); d->widgets.insert(name, checkbox); this->addToInternWidgets(checkbox); connect(checkbox, SIGNAL(toggled(bool)), this, SLOT(updateValue(bool))); connect(checkbox, SIGNAL(destroyed(QObject*)), this, SLOT(removeInternWidget(QObject*))); } else if(variant.type() == QVariant::Int) { QSpinBox *spinbox = new QSpinBox; if(min != QVariant() && max != QVariant()) { spinbox->setMinimum(min.toInt()); spinbox->setMaximum(max.toInt()); d->ranges.insert(name, QPair(min, max)); } if(step != QVariant()) { spinbox->setSingleStep(step.toInt()); d->steps.insert(name, step); } spinbox->setValue(variant.toInt()); d->widgets.insert(name, spinbox); this->addToInternWidgets(spinbox); connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(updateValue(int))); connect(spinbox, SIGNAL(destroyed(QObject*)), this, SLOT(removeInternWidget(QObject*))); } else if(variant.type() == QVariant::Double ) { QDoubleSpinBox *spinbox = new QDoubleSpinBox; if(min != QVariant() && max != QVariant()) { spinbox->setMinimum(min.toDouble()); spinbox->setMaximum(max.toDouble()); d->ranges.insert(name, QPair(min, max)); } if(step != QVariant()) { spinbox->setSingleStep(step.toDouble()); d->steps.insert(name, step); } spinbox->setValue(variant.toDouble()); d->widgets.insert(name, spinbox); this->addToInternWidgets(spinbox); connect(spinbox, SIGNAL(valueChanged(double)), this, SLOT(updateValue(double))); connect(spinbox, SIGNAL(destroyed(QObject*)), this, SLOT(removeInternWidget(QObject*))); } //TODO: to complete with other QVariant types } void medCompositeParameterL::updateValue(bool value) { QCheckBox *checkbox = qobject_cast(QObject::sender()); if(checkbox) { QString name = d->widgets.key(checkbox); d->variants[name] = QVariant(value); emit valuesChanged(d->variants); } } void medCompositeParameterL::updateValue(double value) { QDoubleSpinBox *spinbox = qobject_cast(QObject::sender()); if(spinbox) { QString name = d->widgets.key(spinbox); d->variants[name] = QVariant(value); emit valuesChanged(d->variants); } } void medCompositeParameterL::updateValue(int value) { QSpinBox *spinbox = qobject_cast(QObject::sender()); if(spinbox) { QString name = d->widgets.key(spinbox); d->variants[name] = QVariant(value); emit valuesChanged(d->variants); } } void medCompositeParameterL::removeInternWidget(QObject *widget) { QWidget *w = qobject_cast(widget); if(!w) return; this->removeFromInternWidgets(w); QHashIterator i(d->widgets); while (i.hasNext()) { i.next(); if(w == i.value()) d->widgets.remove(i.key()); } } QList > medCompositeParameterL::ranges() const { return d->ranges.values(); } QList medCompositeParameterL::steps() const { return d->steps.values(); } void medCompositeParameterL::trigger() { emit valuesChanged(d->variants); }