From cba0c543b15218116ba90eba1815b04fae14436b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 26 Apr 2021 10:17:13 +0200 Subject: [PATCH 1/7] Remove unused prototype --- src/skin/legacyskinparser.h | 1 - 1 file changed, 1 deletion(-) 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); From bea44c651e41472726b2394c746f4395f6af1958 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 26 Apr 2021 10:20:29 +0200 Subject: [PATCH 2/7] Skip repeated property updates, cache the QMetaProperty object to avoid hash lookups at runtime. --- src/widget/controlwidgetconnection.cpp | 65 ++++++++++++++++++-------- src/widget/controlwidgetconnection.h | 9 ++-- 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index 2822cb7f3d69..2c89bf58c866 100644 --- a/src/widget/controlwidgetconnection.cpp +++ b/src/widget/controlwidgetconnection.cpp @@ -97,40 +97,67 @@ 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) { + QWidget* pWidget = pBaseWidget->toQWidget(); + VERIFY_OR_DEBUG_ASSERT(pWidget) { + return; + } + const QMetaObject* meta = pWidget->metaObject(); + VERIFY_OR_DEBUG_ASSERT(!propertyName.isEmpty() && meta) { + return; + } + int id = meta->indexOfProperty(propertyName.toLatin1().constData()); + VERIFY_OR_DEBUG_ASSERT(id >= 0) { + return; + } + m_property = meta->property(id); + // skipNoOp = false, during the 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; + double parameter = getControlParameterForValue(v); + QVariant vParameter; + if (m_property.type() == QVariant::Bool) { + vParameter = (parameter > 0); } else { - parameter = getControlParameterForValue(v); + vParameter = parameter; + } + vParameter.convert(m_property.type()); + 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..be128133a19a 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; + QString m_propertyName; + QMetaProperty m_property; + QVariant m_propertyValue; }; From 102aab5fc5e3e68b97f3e042bf003d125ee23d9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 26 Apr 2021 22:19:59 +0200 Subject: [PATCH 3/7] check property name at the very first. --- src/widget/controlwidgetconnection.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index 2c89bf58c866..9db38e4515ac 100644 --- a/src/widget/controlwidgetconnection.cpp +++ b/src/widget/controlwidgetconnection.cpp @@ -103,12 +103,16 @@ ControlWidgetPropertyConnection::ControlWidgetPropertyConnection( const QString& propertyName) : ControlWidgetConnection(pBaseWidget, key, pTransformer), m_propertyName(propertyName) { + VERIFY_OR_DEBUG_ASSERT(!propertyName.isEmpty()) { + return; + } + QWidget* pWidget = pBaseWidget->toQWidget(); VERIFY_OR_DEBUG_ASSERT(pWidget) { return; } const QMetaObject* meta = pWidget->metaObject(); - VERIFY_OR_DEBUG_ASSERT(!propertyName.isEmpty() && meta) { + VERIFY_OR_DEBUG_ASSERT(meta) { return; } int id = meta->indexOfProperty(propertyName.toLatin1().constData()); From e0c49e36546de2da33692a946ce5f70ddf98dd85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 26 Apr 2021 22:26:00 +0200 Subject: [PATCH 4/7] check convert() call during debug --- src/widget/controlwidgetconnection.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index 9db38e4515ac..e3c7093024b0 100644 --- a/src/widget/controlwidgetconnection.cpp +++ b/src/widget/controlwidgetconnection.cpp @@ -142,7 +142,9 @@ void ControlWidgetPropertyConnection::slotControlValueChanged(double v) { } else { vParameter = parameter; } - vParameter.convert(m_property.type()); + bool success = vParameter.convert(m_property.type()); + DEBUG_ASSERT(success); + Q_UNUSED(success); 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 From 2c20cc72be1d129545e8e499375bee7010660263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Mon, 26 Apr 2021 23:06:47 +0200 Subject: [PATCH 5/7] Make m_propety and m_proertyName const --- src/widget/controlwidgetconnection.cpp | 44 +++++++++++++++----------- src/widget/controlwidgetconnection.h | 4 +-- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index e3c7093024b0..b31e4a7cc0a1 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(); + } + 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, @@ -102,25 +124,9 @@ ControlWidgetPropertyConnection::ControlWidgetPropertyConnection( ValueTransformer* pTransformer, const QString& propertyName) : ControlWidgetConnection(pBaseWidget, key, pTransformer), - m_propertyName(propertyName) { - VERIFY_OR_DEBUG_ASSERT(!propertyName.isEmpty()) { - return; - } - - QWidget* pWidget = pBaseWidget->toQWidget(); - VERIFY_OR_DEBUG_ASSERT(pWidget) { - return; - } - const QMetaObject* meta = pWidget->metaObject(); - VERIFY_OR_DEBUG_ASSERT(meta) { - return; - } - int id = meta->indexOfProperty(propertyName.toLatin1().constData()); - VERIFY_OR_DEBUG_ASSERT(id >= 0) { - return; - } - m_property = meta->property(id); - // skipNoOp = false, during the initial update to synchronize the property in all the sub widgets + m_propertyName(propertyName), + m_property(propertyFromWidget(pBaseWidget->toQWidget(), propertyName)) { + // Initial update to synchronize the property in all the sub widgets slotControlValueChanged(m_pControl->get()); } diff --git a/src/widget/controlwidgetconnection.h b/src/widget/controlwidgetconnection.h index be128133a19a..50f96e7af5eb 100644 --- a/src/widget/controlwidgetconnection.h +++ b/src/widget/controlwidgetconnection.h @@ -138,7 +138,7 @@ class ControlWidgetPropertyConnection final : public ControlWidgetConnection { void slotControlValueChanged(double v) override; private: - QString m_propertyName; - QMetaProperty m_property; + const QString m_propertyName; + const QMetaProperty m_property; QVariant m_propertyValue; }; From 1b3cef391d58d4a953772473d2cf958d7ffe48c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 30 Apr 2021 09:14:31 +0200 Subject: [PATCH 6/7] make some locals const --- src/widget/controlwidgetconnection.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index b31e4a7cc0a1..96ce23eb1b98 100644 --- a/src/widget/controlwidgetconnection.cpp +++ b/src/widget/controlwidgetconnection.cpp @@ -22,7 +22,7 @@ QMetaProperty propertyFromWidget(const QWidget* pWidget, const QString& name) { VERIFY_OR_DEBUG_ASSERT(meta) { return QMetaProperty(); } - int id = meta->indexOfProperty(name.toLatin1().constData()); + const int id = meta->indexOfProperty(name.toLatin1().constData()); VERIFY_OR_DEBUG_ASSERT(id >= 0) { return QMetaProperty(); } @@ -89,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); } } @@ -141,7 +141,7 @@ QString ControlWidgetPropertyConnection::toDebugString() const { } void ControlWidgetPropertyConnection::slotControlValueChanged(double v) { - double parameter = getControlParameterForValue(v); + const double parameter = getControlParameterForValue(v); QVariant vParameter; if (m_property.type() == QVariant::Bool) { vParameter = (parameter > 0); From 53e2703101ce283ce7aa7b7c8b76ee064d0603c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sch=C3=BCrmann?= Date: Fri, 30 Apr 2021 11:08:40 +0200 Subject: [PATCH 7/7] Rerturn on conversion error --- src/widget/controlwidgetconnection.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/widget/controlwidgetconnection.cpp b/src/widget/controlwidgetconnection.cpp index 96ce23eb1b98..b6b019154ddf 100644 --- a/src/widget/controlwidgetconnection.cpp +++ b/src/widget/controlwidgetconnection.cpp @@ -149,8 +149,9 @@ void ControlWidgetPropertyConnection::slotControlValueChanged(double v) { vParameter = parameter; } bool success = vParameter.convert(m_property.type()); - DEBUG_ASSERT(success); - Q_UNUSED(success); + 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