diff --git a/src/skin/legacyskinparser.h b/src/skin/legacyskinparser.h index 29d6d62f3a0d..31bc033ea2ac 100644 --- a/src/skin/legacyskinparser.h +++ b/src/skin/legacyskinparser.h @@ -104,7 +104,6 @@ class LegacySkinParser : public QObject, public SkinParser { QWidget* parseSizeAwareStack(const QDomElement& node); QWidget* parseSplitter(const QDomElement& node); void parseSingletonDefinition(const QDomElement& node); - QWidget* parseSingletonContainer(const QDomElement& node); // Visual widgets. QWidget* parseVisual(const QDomElement& node); diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index 2822cb7f3d69..b6b019154ddf 100644 --- a/src/widget/controlwidgetconnection.cpp +++ b/src/widget/controlwidgetconnection.cpp @@ -9,6 +9,28 @@ #include "util/valuetransformer.h" #include "widget/wbasewidget.h" +namespace { + +QMetaProperty propertyFromWidget(const QWidget* pWidget, const QString& name) { + VERIFY_OR_DEBUG_ASSERT(!name.isEmpty()) { + return QMetaProperty(); + } + VERIFY_OR_DEBUG_ASSERT(pWidget) { + return QMetaProperty(); + } + const QMetaObject* meta = pWidget->metaObject(); + VERIFY_OR_DEBUG_ASSERT(meta) { + return QMetaProperty(); + } + const int id = meta->indexOfProperty(name.toLatin1().constData()); + VERIFY_OR_DEBUG_ASSERT(id >= 0) { + return QMetaProperty(); + } + return meta->property(id); +} + +} // namespace + ControlWidgetConnection::ControlWidgetConnection( WBaseWidget* pBaseWidget, const ConfigKey& key, @@ -67,7 +89,7 @@ QString ControlParameterWidgetConnection::toDebugString() const { void ControlParameterWidgetConnection::slotControlValueChanged(double value) { if (m_directionOption & DIR_TO_WIDGET) { - double parameter = getControlParameterForValue(value); + const double parameter = getControlParameterForValue(value); m_pWidget->onConnectedControlChanged(parameter, value); } } @@ -97,40 +119,58 @@ void ControlParameterWidgetConnection::setControlParameterUp(double v) { } ControlWidgetPropertyConnection::ControlWidgetPropertyConnection( - WBaseWidget* pBaseWidget, const ConfigKey& key, - ValueTransformer* pTransformer, const QString& propertyName) + WBaseWidget* pBaseWidget, + const ConfigKey& key, + ValueTransformer* pTransformer, + const QString& propertyName) : ControlWidgetConnection(pBaseWidget, key, pTransformer), - m_propertyName(propertyName.toLatin1()) { + m_propertyName(propertyName), + m_property(propertyFromWidget(pBaseWidget->toQWidget(), propertyName)) { + // Initial update to synchronize the property in all the sub widgets slotControlValueChanged(m_pControl->get()); } QString ControlWidgetPropertyConnection::toDebugString() const { const ConfigKey& key = getKey(); - return QString("%1,%2 Parameter: %3 Property: %4 Value: %5").arg( - key.group, - key.item, - QString::number(m_pControl->getParameter()), - m_propertyName, - m_pWidget->toQWidget()->property(m_propertyName.constData()).toString()); + return QString("%1,%2 Parameter: %3 Property: %4 Value: %5") + .arg(key.group, + key.item, + QString::number(m_pControl->getParameter()), + m_propertyName, + m_property.read(m_pWidget->toQWidget()).toString()); } void ControlWidgetPropertyConnection::slotControlValueChanged(double v) { - QVariant parameter; - QWidget* pWidget = m_pWidget->toQWidget(); - QVariant property = pWidget->property(m_propertyName.constData()); - if (property.type() == QVariant::Bool) { - parameter = getControlParameterForValue(v) > 0; + const double parameter = getControlParameterForValue(v); + QVariant vParameter; + if (m_property.type() == QVariant::Bool) { + vParameter = (parameter > 0); } else { - parameter = getControlParameterForValue(v); + vParameter = parameter; + } + bool success = vParameter.convert(m_property.type()); + VERIFY_OR_DEBUG_ASSERT(success) { + return; + } + if (m_propertyValue == vParameter) { + // don't repeat writing the same value that may stall the GUI + // Comparing the property value directly does not work, because + // in some cases (e.g. visible) it has to be propagated to the child widgets. + return; } - if (!pWidget->setProperty(m_propertyName.constData(),parameter)) { + QWidget* pWidget = m_pWidget->toQWidget(); + if (!m_property.write(pWidget, vParameter)) { + const ConfigKey& key = getKey(); qWarning() << "Property" << m_propertyName - << "was not defined for widget" << pWidget->objectName() - << "of type" << pWidget->metaObject()->className() - << "(parameter:" << parameter << ")"; + << "was not defined for widget" << pWidget + << "(parameter:" << parameter << ")" + << key.group << key.item; + return; } + m_propertyValue = vParameter; + // According to http://stackoverflow.com/a/3822243 this is the least // expensive way to restyle just this widget. pWidget->style()->unpolish(pWidget); diff --git a/src/widget/controlwidgetconnection.h b/src/widget/controlwidgetconnection.h index 0b487dedd967..50f96e7af5eb 100644 --- a/src/widget/controlwidgetconnection.h +++ b/src/widget/controlwidgetconnection.h @@ -1,9 +1,10 @@ #pragma once +#include +#include #include -#include #include -#include +#include #include "control/controlproxy.h" #include "util/valuetransformer.h" @@ -137,5 +138,7 @@ class ControlWidgetPropertyConnection final : public ControlWidgetConnection { void slotControlValueChanged(double v) override; private: - QByteArray m_propertyName; + const QString m_propertyName; + const QMetaProperty m_property; + QVariant m_propertyValue; };