diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-03-08 13:15:39 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2023-03-13 06:49:21 +0000 |
commit | 30784e55e484de2790c4b264a50a65acf450c000 (patch) | |
tree | d6370f3ce99a976fe3a175027bfc2441b420ba17 | |
parent | 982b550541cc68670cad222e921fd62a4c1f232c (diff) |
convert UnoControlModel and friends to use std::mutex
Which means creating a variant of the cppuhelper::OPropertySetHelper
helper class which uses a std::mutex.
Since we can do virtual base classes now (which the original could not), use that and a new helper
class comphelper::UnoImplBase to share
std::mutex m_aMutex;
bool m_bDisposing;
fields that the OPropertySetHelper wants to share with the parent class.
Change-Id: I05ad465a3d3653ed4e109137e3e1c58190da8d97
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148474
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
29 files changed, 1547 insertions, 292 deletions
diff --git a/comphelper/Library_comphelper.mk b/comphelper/Library_comphelper.mk index 5238cb65e968..f75dc446cdd2 100644 --- a/comphelper/Library_comphelper.mk +++ b/comphelper/Library_comphelper.mk @@ -155,6 +155,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\ comphelper/source/property/propertystatecontainer \ comphelper/source/property/propmultiplex \ comphelper/source/property/propmultiplex2 \ + comphelper/source/property/propshlp \ comphelper/source/property/propstate \ comphelper/source/streaming/basicio \ comphelper/source/streaming/memorystream \ diff --git a/comphelper/source/property/propshlp.cxx b/comphelper/source/property/propshlp.cxx new file mode 100644 index 000000000000..3071dfd4a32d --- /dev/null +++ b/comphelper/source/property/propshlp.cxx @@ -0,0 +1,880 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <osl/diagnose.h> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/queryinterface.hxx> +#include <comphelper/propshlp.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <memory> +#include <sal/log.hxx> + +using namespace osl; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +using namespace cppu; + +namespace comphelper +{ +extern "C" { + +static int compare_OUString_Property_Impl(const void* arg1, const void* arg2) SAL_THROW_EXTERN_C() +{ + return static_cast<OUString const*>(arg1)->compareTo(static_cast<Property const*>(arg2)->Name); +} +} + +/** + * The class which implements the PropertySetInfo interface. + */ + +namespace +{ +class OPropertySetHelperInfo_Impl : public WeakImplHelper<css::beans::XPropertySetInfo> +{ + Sequence<Property> aInfos; + +public: + explicit OPropertySetHelperInfo_Impl(IPropertyArrayHelper& rHelper_); + + // XPropertySetInfo-methods + virtual Sequence<Property> SAL_CALL getProperties() override; + virtual Property SAL_CALL getPropertyByName(const OUString& PropertyName) override; + virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& PropertyName) override; +}; +} + +/** + * Create an object that implements XPropertySetInfo IPropertyArrayHelper. + */ +OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(IPropertyArrayHelper& rHelper_) + : aInfos(rHelper_.getProperties()) +{ +} + +/** + * Return the sequence of properties, which are provided through the constructor. + */ +Sequence<Property> OPropertySetHelperInfo_Impl::getProperties() { return aInfos; } + +/** + * Return the sequence of properties, which are provided through the constructor. + */ +Property OPropertySetHelperInfo_Impl::getPropertyByName(const OUString& PropertyName) +{ + Property* pR + = static_cast<Property*>(bsearch(&PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof(Property), compare_OUString_Property_Impl)); + if (!pR) + throw UnknownPropertyException(PropertyName); + + return *pR; +} + +/** + * Return the sequence of properties, which are provided through the constructor. + */ +sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName(const OUString& PropertyName) +{ + Property* pR + = static_cast<Property*>(bsearch(&PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof(Property), compare_OUString_Property_Impl)); + return pR != nullptr; +} + +OPropertySetHelper::OPropertySetHelper() {} + +OPropertySetHelper::OPropertySetHelper(bool bIgnoreRuntimeExceptionsWhileFiring) + : m_bIgnoreRuntimeExceptionsWhileFiring(bIgnoreRuntimeExceptionsWhileFiring) +{ +} + +OPropertySetHelper::OPropertySetHelper(cppu::IEventNotificationHook* i_pFireEvents, + bool bIgnoreRuntimeExceptionsWhileFiring) + : m_pFireEvents(i_pFireEvents) + , m_bIgnoreRuntimeExceptionsWhileFiring(bIgnoreRuntimeExceptionsWhileFiring) +{ +} + +/** + * You must call disposing before. + */ +OPropertySetHelper::~OPropertySetHelper() {} + +// XInterface +Any OPropertySetHelper::queryInterface(const css::uno::Type& rType) +{ + return ::cppu::queryInterface(rType, static_cast<XPropertySet*>(this), + static_cast<XMultiPropertySet*>(this), + static_cast<XFastPropertySet*>(this)); +} + +/** + * called from the derivee's XTypeProvider::getTypes implementation + */ +css::uno::Sequence<css::uno::Type> OPropertySetHelper::getTypes() +{ + return { UnoType<css::beans::XPropertySet>::get(), + UnoType<css::beans::XMultiPropertySet>::get(), + UnoType<css::beans::XFastPropertySet>::get() }; +} + +// ComponentHelper +void OPropertySetHelper::disposing(std::unique_lock<std::mutex>& rGuard) +{ + // Create an event with this as sender + Reference<XPropertySet> rSource = this; + EventObject aEvt; + aEvt.Source = rSource; + + // inform all listeners to release this object + // The listener containers are automatically cleared + aBoundLC.disposeAndClear(rGuard, aEvt); + aVetoableLC.disposeAndClear(rGuard, aEvt); +} + +Reference<XPropertySetInfo> +OPropertySetHelper::createPropertySetInfo(IPropertyArrayHelper& rProperties) +{ + return new OPropertySetHelperInfo_Impl(rProperties); +} + +// XPropertySet +void OPropertySetHelper::setPropertyValue(const OUString& rPropertyName, const Any& rValue) +{ + std::unique_lock aGuard(m_aMutex); + setPropertyValueImpl(aGuard, rPropertyName, rValue); +} + +void OPropertySetHelper::setPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + const OUString& rPropertyName, const Any& rValue) +{ + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + // call the method of the XFastPropertySet interface + setFastPropertyValueImpl(rGuard, nHandle, rValue); +} + +// XPropertySet +Any OPropertySetHelper::getPropertyValue(const OUString& rPropertyName) +{ + std::unique_lock aGuard(m_aMutex); + return getPropertyValueImpl(aGuard, rPropertyName); +} + +Any OPropertySetHelper::getPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + const OUString& rPropertyName) +{ + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + // call the method of the XFastPropertySet interface + Any aAny; + getFastPropertyValue(rGuard, aAny, nHandle); + return aAny; +} + +// XPropertySet +void OPropertySetHelper::addPropertyChangeListener( + const OUString& rPropertyName, const Reference<XPropertyChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + if (m_bDisposed) + return; + + // only add listeners if you are not disposed + // a listener with no name means all properties + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + { + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + } + + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle); + if (!(nAttributes & css::beans::PropertyAttribute::BOUND)) + { + OSL_FAIL("add listener to an unbound property"); + // silent ignore this + return; + } + // add the change listener to the helper container + aBoundLC.addInterface(aGuard, nHandle, rxListener); + } + else + // add the change listener to the helper container + maPropertyChangeListeners.addInterface(aGuard, rxListener); +} + +// XPropertySet +void OPropertySetHelper::removePropertyChangeListener( + const OUString& rPropertyName, const Reference<XPropertyChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + // all listeners are automatically released in a dispose call + if (m_bDisposed) + return; + + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + aBoundLC.removeInterface(aGuard, nHandle, rxListener); + } + else + { + // remove the change listener to the helper container + maPropertyChangeListeners.removeInterface(aGuard, rxListener); + } +} + +// XPropertySet +void OPropertySetHelper::addVetoableChangeListener( + const OUString& rPropertyName, const Reference<XVetoableChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + if (m_bDisposed) + return; + + // only add listeners if you are not disposed + // a listener with no name means all properties + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + { + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + } + + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle); + if (!(nAttributes & PropertyAttribute::CONSTRAINED)) + { + OSL_FAIL("addVetoableChangeListener, and property is not constrained"); + // silent ignore this + return; + } + // add the vetoable listener to the helper container + aVetoableLC.addInterface(aGuard, nHandle, rxListener); + } + else + // add the vetoable listener to the helper container + maVetoableChangeListeners.addInterface(aGuard, rxListener); +} + +// XPropertySet +void OPropertySetHelper::removeVetoableChangeListener( + const OUString& rPropertyName, const Reference<XVetoableChangeListener>& rxListener) +{ + std::unique_lock aGuard(m_aMutex); + OSL_ENSURE(!m_bDisposed, "object is disposed"); + // all listeners are automatically released in a dispose call + if (m_bDisposed) + return; + + if (!rPropertyName.isEmpty()) + { + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // map the name to the handle + sal_Int32 nHandle = rPH.getHandleByName(rPropertyName); + if (nHandle == -1) + { + // property not known throw exception + throw UnknownPropertyException(rPropertyName); + } + // remove the vetoable listener to the helper container + aVetoableLC.removeInterface(aGuard, nHandle, rxListener); + } + else + // add the vetoable listener to the helper container + maVetoableChangeListeners.removeInterface(aGuard, rxListener); +} + +void OPropertySetHelper::setDependentFastPropertyValue(std::unique_lock<std::mutex>& rGuard, + sal_Int32 i_handle, + const css::uno::Any& i_value) +{ + sal_Int16 nAttributes(0); + IPropertyArrayHelper& rInfo = getInfoHelper(); + if (!rInfo.fillPropertyMembersByHandle(nullptr, &nAttributes, i_handle)) + // unknown property + throw UnknownPropertyException(OUString::number(i_handle)); + + // no need to check for READONLY-ness of the property. The method is intended to be called internally, which + // implies it might be invoked for properties which are read-only to the instance's clients, but well allowed + // to change their value. + + Any aConverted, aOld; + bool bChanged = convertFastPropertyValue(rGuard, aConverted, aOld, i_handle, i_value); + if (!bChanged) + return; + + // don't fire vetoable events. This method is called with our mutex locked, so calling into listeners would not be + // a good idea. The caller is responsible for not invoking this for constrained properties. + OSL_ENSURE((nAttributes & PropertyAttribute::CONSTRAINED) == 0, + "OPropertySetHelper::setDependentFastPropertyValue: not to be used for constrained " + "properties!"); + + // actually set the new value + try + { + setFastPropertyValue_NoBroadcast(rGuard, i_handle, aConverted); + } + catch (const UnknownPropertyException&) + { + throw; /* allowed to leave */ + } + catch (const PropertyVetoException&) + { + throw; /* allowed to leave */ + } + catch (const IllegalArgumentException&) + { + throw; /* allowed to leave */ + } + catch (const WrappedTargetException&) + { + throw; /* allowed to leave */ + } + catch (const RuntimeException&) + { + throw; /* allowed to leave */ + } + catch (const Exception&) + { + // not allowed to leave this method + WrappedTargetException aWrapped; + aWrapped.TargetException = ::cppu::getCaughtException(); + aWrapped.Context = static_cast<XPropertySet*>(this); + throw aWrapped; + } + + // remember the handle/values, for the events to be fired later + m_handles.push_back(i_handle); + m_newValues.push_back( + aConverted); // TODO: setFastPropertyValue notifies the unconverted value here ...? + m_oldValues.push_back(aOld); +} + +// XFastPropertySet +void OPropertySetHelper::setFastPropertyValue(sal_Int32 nHandle, const Any& rValue) +{ + std::unique_lock aGuard(m_aMutex); + setFastPropertyValueImpl(aGuard, nHandle, rValue); +} + +void OPropertySetHelper::setFastPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + sal_Int32 nHandle, const Any& rValue) +{ + OSL_ENSURE(!m_bDisposed, "object is disposed"); + + IPropertyArrayHelper& rInfo = getInfoHelper(); + sal_Int16 nAttributes; + if (!rInfo.fillPropertyMembersByHandle(nullptr, &nAttributes, nHandle)) + { + // unknown property + throw UnknownPropertyException(OUString::number(nHandle)); + } + if (nAttributes & PropertyAttribute::READONLY) + throw PropertyVetoException(); + + Any aConvertedVal; + Any aOldVal; + + // Will the property change? + bool bChanged = convertFastPropertyValue(rGuard, aConvertedVal, aOldVal, nHandle, rValue); + if (!bChanged) + return; + + // Is it a constrained property? + if (nAttributes & PropertyAttribute::CONSTRAINED) + { + // In aValue is the converted rValue + // fire a constrained event + // second parameter NULL means constrained + fire(rGuard, &nHandle, &rValue, &aOldVal, 1, true); + } + + try + { + // set the property to the new value + setFastPropertyValue_NoBroadcast(rGuard, nHandle, aConvertedVal); + } + catch (const css::beans::UnknownPropertyException&) + { + throw; /* allowed to leave */ + } + catch (const css::beans::PropertyVetoException&) + { + throw; /* allowed to leave */ + } + catch (const css::lang::IllegalArgumentException&) + { + throw; /* allowed to leave */ + } + catch (const css::lang::WrappedTargetException&) + { + throw; /* allowed to leave */ + } + catch (const css::uno::RuntimeException&) + { + throw; /* allowed to leave */ + } + catch (const css::uno::Exception& e) + { + // not allowed to leave this method + css::lang::WrappedTargetException aWrap; + aWrap.Context = static_cast<css::beans::XPropertySet*>(this); + aWrap.TargetException <<= e; + + throw aWrap; + } + + // file a change event, if the value changed + impl_fireAll(rGuard, &nHandle, &rValue, &aOldVal, 1); +} + +// XFastPropertySet +Any OPropertySetHelper::getFastPropertyValue(sal_Int32 nHandle) +{ + IPropertyArrayHelper& rInfo = getInfoHelper(); + if (!rInfo.fillPropertyMembersByHandle(nullptr, nullptr, nHandle)) + // unknown property + throw UnknownPropertyException(OUString::number(nHandle)); + + Any aRet; + std::unique_lock aGuard(m_aMutex); + getFastPropertyValue(aGuard, aRet, nHandle); + return aRet; +} + +void OPropertySetHelper::impl_fireAll(std::unique_lock<std::mutex>& rGuard, sal_Int32* i_handles, + const Any* i_newValues, const Any* i_oldValues, + sal_Int32 i_count) +{ + if (m_handles.empty()) + { + fire(rGuard, i_handles, i_newValues, i_oldValues, i_count, false); + return; + } + + const size_t additionalEvents = m_handles.size(); + OSL_ENSURE(additionalEvents == m_newValues.size() && additionalEvents == m_oldValues.size(), + "OPropertySetHelper::impl_fireAll: inconsistency!"); + + std::vector<sal_Int32> allHandles(additionalEvents + i_count); + std::copy(m_handles.begin(), m_handles.end(), allHandles.begin()); + std::copy(i_handles, i_handles + i_count, allHandles.begin() + additionalEvents); + + std::vector<Any> allNewValues(additionalEvents + i_count); + std::copy(m_newValues.begin(), m_newValues.end(), allNewValues.begin()); + std::copy(i_newValues, i_newValues + i_count, allNewValues.begin() + additionalEvents); + + std::vector<Any> allOldValues(additionalEvents + i_count); + std::copy(m_oldValues.begin(), m_oldValues.end(), allOldValues.begin()); + std::copy(i_oldValues, i_oldValues + i_count, allOldValues.begin() + additionalEvents); + + m_handles.clear(); + m_newValues.clear(); + m_oldValues.clear(); + + fire(rGuard, allHandles.data(), allNewValues.data(), allOldValues.data(), + additionalEvents + i_count, false); +} + +void OPropertySetHelper::fire(std::unique_lock<std::mutex>& rGuard, sal_Int32* pnHandles, + const Any* pNewValues, const Any* pOldValues, + sal_Int32 nHandles, // This is the Count of the array + bool bVetoable) +{ + if (!m_bFireEvents) + return; + + if (m_pFireEvents) + { + m_pFireEvents->fireEvents(pnHandles, nHandles, bVetoable, + m_bIgnoreRuntimeExceptionsWhileFiring); + } + + // Only fire, if one or more properties changed + if (!nHandles) + return; + + // create the event sequence of all changed properties + Sequence<PropertyChangeEvent> aEvts(nHandles); + PropertyChangeEvent* pEvts = aEvts.getArray(); + Reference<XInterface> xSource(static_cast<XPropertySet*>(this), UNO_QUERY); + sal_Int32 i; + sal_Int32 nChangesLen = 0; + // Loop over all changed properties to fill the event struct + for (i = 0; i < nHandles; i++) + { + // Vetoable fire and constrained attribute set or + // Change fire and Changed and bound attribute set + IPropertyArrayHelper& rInfo = getInfoHelper(); + sal_Int16 nAttributes; + OUString aPropName; + rInfo.fillPropertyMembersByHandle(&aPropName, &nAttributes, pnHandles[i]); + + if ((bVetoable && (nAttributes & PropertyAttribute::CONSTRAINED)) + || (!bVetoable && (nAttributes & PropertyAttribute::BOUND))) + { + pEvts[nChangesLen].Source = xSource; + pEvts[nChangesLen].PropertyName = aPropName; + pEvts[nChangesLen].PropertyHandle = pnHandles[i]; + pEvts[nChangesLen].OldValue = pOldValues[i]; + pEvts[nChangesLen].NewValue = pNewValues[i]; + nChangesLen++; + } + } + + bool bIgnoreRuntimeExceptionsWhileFiring = m_bIgnoreRuntimeExceptionsWhileFiring; + + // fire the events for all changed properties + for (i = 0; i < nChangesLen; i++) + { + if (bVetoable) // fire change Events? + fireVetoableChangeListeners( + rGuard, aVetoableLC.getContainer(rGuard, pEvts[i].PropertyHandle), pEvts[i]); + else + // get the listener container for the property name + firePropertyChangeListeners( + rGuard, aBoundLC.getContainer(rGuard, pEvts[i].PropertyHandle), pEvts[i]); + + // broadcast to all listeners with "" property name + if (bVetoable) + // fire change Events? + fireVetoableChangeListeners(rGuard, &maVetoableChangeListeners, pEvts[i]); + else + firePropertyChangeListeners(rGuard, &maPropertyChangeListeners, pEvts[i]); + } + + // reduce array to changed properties + aEvts.realloc(nChangesLen); + + if (bVetoable) + return; + + if (!maPropertiesChangeListeners.getLength(rGuard)) + return; + + // Here is a Bug, unbound properties are also fired + OInterfaceIteratorHelper4 aIt(rGuard, maPropertiesChangeListeners); + while (aIt.hasMoreElements()) + { + XPropertiesChangeListener* pL = aIt.next().get(); + rGuard.unlock(); + try + { + try + { + // fire the whole event sequence to the + // XPropertiesChangeListener's + pL->propertiesChange(aEvts); + } + catch (DisposedException& exc) + { + OSL_ENSURE(exc.Context.is(), "DisposedException without Context!"); + if (exc.Context == pL) + { + rGuard.lock(); + aIt.remove(rGuard); + rGuard.unlock(); + } + else + throw; + } + } + catch (RuntimeException& exc) + { + SAL_INFO("cppuhelper", "caught RuntimeException while firing listeners: " << exc); + if (!bIgnoreRuntimeExceptionsWhileFiring) + throw; + } + rGuard.lock(); + } +} + +void OPropertySetHelper::fireVetoableChangeListeners( + std::unique_lock<std::mutex>& rGuard, + comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener>* pListeners, + const css::beans::PropertyChangeEvent& rChangeEvent) +{ + if (!pListeners || !pListeners->getLength(rGuard)) + return; + // Iterate over all listeners and send events + OInterfaceIteratorHelper4 aIt(rGuard, *pListeners); + while (aIt.hasMoreElements()) + { + XVetoableChangeListener* pL = aIt.next().get(); + rGuard.unlock(); + try + { + try + { + pL->vetoableChange(rChangeEvent); + } + catch (DisposedException& exc) + { + OSL_ENSURE(exc.Context.is(), "DisposedException without Context!"); + if (exc.Context == pL) + { + rGuard.lock(); + aIt.remove(rGuard); + rGuard.unlock(); + } + else + throw; + } + } + catch (RuntimeException& exc) + { + SAL_INFO("cppuhelper", "caught RuntimeException while firing listeners: " << exc); + if (!m_bIgnoreRuntimeExceptionsWhileFiring) + throw; + } + rGuard.lock(); + } +} + +void OPropertySetHelper::firePropertyChangeListeners( + std::unique_lock<std::mutex>& rGuard, + comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener>* pListeners, + const css::beans::PropertyChangeEvent& rChangeEvent) +{ + if (!pListeners || !pListeners->getLength(rGuard)) + return; + // Iterate over all listeners and send events + OInterfaceIteratorHelper4 aIt(rGuard, *pListeners); + while (aIt.hasMoreElements()) + { + XPropertyChangeListener* pL = aIt.next().get(); + rGuard.unlock(); + try + { + try + { + pL->propertyChange(rChangeEvent); + } + catch (DisposedException& exc) + { + OSL_ENSURE(exc.Context.is(), "DisposedException without Context!"); + if (exc.Context == pL) + { + rGuard.lock(); + aIt.remove(rGuard); + rGuard.unlock(); + } + else + throw; + } + } + catch (RuntimeException& exc) + { + SAL_INFO("cppuhelper", "caught RuntimeException while firing listeners: " << exc); + if (!m_bIgnoreRuntimeExceptionsWhileFiring) + throw; + } + rGuard.lock(); + } +} + +// OPropertySetHelper +void OPropertySetHelper::setFastPropertyValues(std::unique_lock<std::mutex>& rGuard, + sal_Int32 nSeqLen, sal_Int32* pHandles, + const Any* pValues, sal_Int32 nHitCount) +{ + OSL_ENSURE(!m_bDisposed, "object is disposed"); + + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + + std::unique_ptr<Any[]> pConvertedValues(new Any[nHitCount]); + std::unique_ptr<Any[]> pOldValues(new Any[nHitCount]); + sal_Int32 n = 0; + sal_Int32 i; + + for (i = 0; i < nSeqLen; i++) + { + if (pHandles[i] != -1) + { + sal_Int16 nAttributes; + rPH.fillPropertyMembersByHandle(nullptr, &nAttributes, pHandles[i]); + if (nAttributes & PropertyAttribute::READONLY) + throw PropertyVetoException(); + // Will the property change? + if (convertFastPropertyValue(rGuard, pConvertedValues[n], pOldValues[n], pHandles[i], + pValues[i])) + { + // only increment if the property really change + pHandles[n] = pHandles[i]; + n++; + } + } + } + + // fire vetoable events + fire(rGuard, pHandles, pConvertedValues.get(), pOldValues.get(), n, true); + + // Loop over all changed properties + for (i = 0; i < n; i++) + { + // Will the property change? + setFastPropertyValue_NoBroadcast(rGuard, pHandles[i], pConvertedValues[i]); + } + + // fire change events + impl_fireAll(rGuard, pHandles, pConvertedValues.get(), pOldValues.get(), n); +} + +// XMultiPropertySet +/** + * The sequence may be contain not known properties. The implementation + * must ignore these properties. + */ +void OPropertySetHelper::setPropertyValues(const Sequence<OUString>& rPropertyNames, + const Sequence<Any>& rValues) +{ + sal_Int32 nSeqLen = rPropertyNames.getLength(); + if (nSeqLen != rValues.getLength()) + throw IllegalArgumentException("lengths do not match", static_cast<XPropertySet*>(this), + -1); + std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nSeqLen]); + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // fill the handle array + sal_Int32 nHitCount = rPH.fillHandles(pHandles.get(), rPropertyNames); + if (nHitCount == 0) + return; + std::unique_lock aGuard(m_aMutex); + setFastPropertyValues(aGuard, nSeqLen, pHandles.get(), rValues.getConstArray(), nHitCount); +} + +// XMultiPropertySet +Sequence<Any> OPropertySetHelper::getPropertyValues(const Sequence<OUString>& rPropertyNames) +{ + sal_Int32 nSeqLen = rPropertyNames.getLength(); + std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nSeqLen]); + Sequence<Any> aValues(nSeqLen); + + // get the map table + IPropertyArrayHelper& rPH = getInfoHelper(); + // fill the handle array + rPH.fillHandles(pHandles.get(), rPropertyNames); + + Any* pValues = aValues.getArray(); + + std::unique_lock aGuard(m_aMutex); + // fill the sequence with the values + for (sal_Int32 i = 0; i < nSeqLen; i++) + getFastPropertyValue(aGuard, pValues[i], pHandles[i]); + + return aValues; +} + +// XMultiPropertySet +void OPropertySetHelper::addPropertiesChangeListener( + const Sequence<OUString>&, const Reference<XPropertiesChangeListener>& rListener) +{ + std::unique_lock g(m_aMutex); + maPropertiesChangeListeners.addInterface(g, rListener); +} + +// XMultiPropertySet +void OPropertySetHelper::removePropertiesChangeListener( + const Reference<XPropertiesChangeListener>& rListener) +{ + std::unique_lock g(m_aMutex); + maPropertiesChangeListeners.removeInterface(g, rListener); +} + +// XMultiPropertySet +void OPropertySetHelper::firePropertiesChangeEvent( + const Sequence<OUString>& rPropertyNames, const Reference<XPropertiesChangeListener>& rListener) +{ + sal_Int32 nLen = rPropertyNames.getLength(); + std::unique_ptr<sal_Int32[]> pHandles(new sal_Int32[nLen]); + IPropertyArrayHelper& rPH = getInfoHelper(); + rPH.fillHandles(pHandles.get(), rPropertyNames); + const OUString* pNames = rPropertyNames.getConstArray(); + + // get the count of matching properties + sal_Int32 nFireLen = 0; + sal_Int32 i; + for (i = 0; i < nLen; i++) + if (pHandles[i] != -1) + nFireLen++; + + Sequence<PropertyChangeEvent> aChanges(nFireLen); + PropertyChangeEvent* pChanges = aChanges.getArray(); + + { + // must lock the mutex outside the loop. So all values are consistent. + std::unique_lock aGuard(m_aMutex); + Reference<XInterface> xSource(static_cast<XPropertySet*>(this), UNO_QUERY); + sal_Int32 nFirePos = 0; + for (i = 0; i < nLen; i++) + { + if (pHandles[i] != -1) + { + pChanges[nFirePos].Source = xSource; + pChanges[nFirePos].PropertyName = pNames[i]; + pChanges[nFirePos].PropertyHandle = pHandles[i]; + getFastPropertyValue(aGuard, pChanges[nFirePos].OldValue, pHandles[i]); + pChanges[nFirePos].NewValue = pChanges[nFirePos].OldValue; + nFirePos++; + } + } + // release guard to fire events + } + if (nFireLen) + rListener->propertiesChange(aChanges); +} + +UnoImplBase::~UnoImplBase() {} + +} // end namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/compbase.hxx b/include/comphelper/compbase.hxx index 6cde1fbb5f74..280d3d26b554 100644 --- a/include/comphelper/compbase.hxx +++ b/include/comphelper/compbase.hxx @@ -13,6 +13,7 @@ #include <comphelper/comphelperdllapi.h> #include <comphelper/interfacecontainer4.hxx> +#include <comphelper/unoimplbase.hxx> #include <cppuhelper/weak.hxx> #include <cppuhelper/queryinterface.hxx> #include <cppuhelper/implbase.hxx> @@ -28,7 +29,8 @@ namespace comphelper (2) helps to handle the custom where we have conflicting interfaces e.g. multiple UNO interfaces that extend css::lang::XComponent */ -class COMPHELPER_DLLPUBLIC WeakComponentImplHelperBase : public cppu::OWeakObject, +class COMPHELPER_DLLPUBLIC WeakComponentImplHelperBase : public virtual comphelper::UnoImplBase, + public cppu::OWeakObject, public css::lang::XComponent { public: @@ -56,8 +58,6 @@ protected: throw css::lang::DisposedException(OUString(), static_cast<cppu::OWeakObject*>(this)); } comphelper::OInterfaceContainerHelper4<css::lang::XEventListener> maEventListeners; - mutable std::mutex m_aMutex; - bool m_bDisposed = false; }; template <typename... Ifc> diff --git a/include/comphelper/propshlp.hxx b/include/comphelper/propshlp.hxx new file mode 100644 index 000000000000..e982077166cf --- /dev/null +++ b/include/comphelper/propshlp.hxx @@ -0,0 +1,348 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ +#pragma once + +#include <comphelper/multiinterfacecontainer4.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XPropertySetOption.hpp> +#include <com/sun/star/beans/XMultiPropertySet.hpp> +#include <com/sun/star/beans/XFastPropertySet.hpp> + +#include <comphelper/comphelperdllapi.h> +#include <comphelper/unoimplbase.hxx> +#include <cppuhelper/propshlp.hxx> + +namespace comphelper +{ +/************************************************************************* +*************************************************************************/ + +/** + This abstract class maps the methods of the interfaces XMultiPropertySet, XFastPropertySet + and XPropertySet to the methods getInfoHelper, convertFastPropertyValue, + setFastPropertyValue_NoBroadcast and getFastPropertyValue. You must derive from + this class and override the methods. + It provides a standard implementation of the XPropertySetInfo. + + This is a modified copy of the cppuhelper::OPropertySetHelper class, except + that is uses std::mutex instead of osl::Mutex. + */ +class COMPHELPER_DLLPUBLIC OPropertySetHelper : public virtual comphelper::UnoImplBase, + public css::beans::XMultiPropertySet, + public css::beans::XFastPropertySet, + public css::beans::XPropertySet +{ +public: + OPropertySetHelper(); + + /** Constructor. + + @param bIgnoreRuntimeExceptionsWhileFiring + indicates whether occurring RuntimeExceptions will be + ignored when firing notifications + (vetoableChange(), propertyChange()) + to listeners. + PropertyVetoExceptions may still be thrown. + This flag is useful in an inter-process scenario when + remote bridges may break down + (firing DisposedExceptions). + */ + OPropertySetHelper(bool bIgnoreRuntimeExceptionsWhileFiring); + + /** Constructor. + + @param i_pFireEvents + additional event notifier + + @param bIgnoreRuntimeExceptionsWhileFiring + indicates whether occurring RuntimeExceptions will be + ignored when firing notifications + (vetoableChange(), propertyChange()) + to listeners. + PropertyVetoExceptions may still be thrown. + This flag is useful in an inter-process scenario when + remote bridges may break down + (firing DisposedExceptions). + */ + OPropertySetHelper(cppu::IEventNotificationHook* i_pFireEvents, + bool bIgnoreRuntimeExceptionsWhileFiring = false); + + /** + Only returns a reference to XMultiPropertySet, XFastPropertySet, XPropertySet and + XEventListener. + */ + virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type& rType) override; + + /** eases implementing XTypeProvider::getTypes, returns the types of XMultiPropertySet, XFastPropertySet, XPropertySet + + @throws css::uno::RuntimeException + */ + static css::uno::Sequence<css::uno::Type> getTypes(); + + /** + Send a disposing notification to the listeners + + @see OComponentHelper + */ + void disposing(std::unique_lock<std::mutex>& rGuard); + + /** + Throw UnknownPropertyException or PropertyVetoException if the property with the name + rPropertyName does not exist or is readonly. Otherwise rPropertyName is changed to its handle + value and setFastPropertyValue is called. + */ + virtual void SAL_CALL setPropertyValue(const ::rtl::OUString& rPropertyName, + const css::uno::Any& aValue) override final; + /** + Throw UnknownPropertyException if the property with the name + rPropertyName does not exist. + */ + virtual css::uno::Any SAL_CALL + getPropertyValue(const ::rtl::OUString& aPropertyName) override final; + /** Ignored if the property is not bound. */ + virtual void SAL_CALL addPropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override; + + /** Ignored if the property is not bound. */ + virtual void SAL_CALL removePropertyChangeListener( + const ::rtl::OUString& aPropertyName, + const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override; + + /** Ignored if the property is not constrained. */ + virtual void SAL_CALL addVetoableChangeListener( + const ::rtl::OUString& aPropertyName, + const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override; + + /** Ignored if the property is not constrained. */ + virtual void SAL_CALL removeVetoableChangeListener( + const ::rtl::OUString& aPropertyName, + const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override; + + /** + Throw UnknownPropertyException or PropertyVetoException if the property with the name + rPropertyName does not exist or is readonly. Otherwise the method convertFastPropertyValue + is called, then the vetoable listeners are notified. After this the value of the property + is changed with the setFastPropertyValue_NoBroadcast method and the bound listeners are + notified. + */ + virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, + const css::uno::Any& rValue) override final; + + /** + @exception css::beans::UnknownPropertyException + if the property with the handle nHandle does not exist. + */ + virtual css::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) override final; + + // XMultiPropertySet + virtual void SAL_CALL + setPropertyValues(const css::uno::Sequence<::rtl::OUString>& PropertyNames, + const css::uno::Sequence<css::uno::Any>& Values) override; + + virtual css::uno::Sequence<css::uno::Any> SAL_CALL + getPropertyValues(const css::uno::Sequence<::rtl::OUString>& PropertyNames) override; + + virtual void SAL_CALL addPropertiesChangeListener( + const css::uno::Sequence<::rtl::OUString>& PropertyNames, + const css::uno::Reference<css::beans::XPropertiesChangeListener>& Listener) override; + + virtual void SAL_CALL removePropertiesChangeListener( + const css::uno::Reference<css::beans::XPropertiesChangeListener>& Listener) override; + + virtual void SAL_CALL firePropertiesChangeEvent( + const css::uno::Sequence<::rtl::OUString>& PropertyNames, + const css::uno::Reference<css::beans::XPropertiesChangeListener>& Listener) override; + + /** + The property sequence is created in the call. The interface isn't used after the call. + */ + static css::uno::Reference<css::beans::XPropertySetInfo> + createPropertySetInfo(cppu::IPropertyArrayHelper& rProperties); + +protected: + /** + You must call disposing() before destruction. + */ + ~OPropertySetHelper(); + + /** Override this if you need to do something special during setPropertyValue */ + virtual void setPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + const ::rtl::OUString& rPropertyName, + const css::uno::Any& aValue); + /** Override this if you need to do something special during setFastPropertyValue */ + virtual void setFastPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, + const css::uno::Any& rValue); + /** Override this if you need to do something special during getPropertyValue */ + virtual css::uno::Any getPropertyValueImpl(std::unique_lock<std::mutex>& rGuard, + const ::rtl::OUString& aPropertyName); + + /** + This method fire events to all registered property listeners. + @param pnHandles the id's of the properties that changed. + @param pNewValues the new values of the properties. + @param pOldValues the old values of the properties. + @param nCount the number of elements in the arrays pnHandles, pNewValues and pOldValues. + @param bVetoable true means fire to VetoableChangeListener, false means fire to + XPropertyChangedListener and XMultiPropertyChangedListener. + */ + void fire(std::unique_lock<std::mutex>& rGuard, sal_Int32* pnHandles, + const css::uno::Any* pNewValues, const css::uno::Any* pOldValues, sal_Int32 nCount, + bool bVetoable); + + /** + Set multiple properties with the handles. + @param nSeqLen the length of the arrays pHandles and Values. + @param pHandles the handles of the properties. The number of elements + in the Values sequence is the length of the handle array. A value of -1 + of a handle means invalid property. These are ignored. + @param pValues the values of the properties. + @param nHitCount the number of valid entries in the handle array. + */ + void setFastPropertyValues(std::unique_lock<std::mutex>& rGuard, sal_Int32 nSeqLen, + sal_Int32* pHandles, const css::uno::Any* pValues, + sal_Int32 nHitCount); + + /** + This abstract method must return the name to index table. This table contains all property + names and types of this object. The method is not implemented in this class. + */ + virtual cppu::IPropertyArrayHelper& getInfoHelper() = 0; + + /** + Converted the value rValue and return the result in rConvertedValue and the + old value in rOldValue. An IllegalArgumentException is thrown. + The method is not implemented in this class. After this call the vetoable + listeners are notified. + + @param rConvertedValue the converted value. Only set if return is true. + @param rOldValue the old value. Only set if return is true. + @param nHandle the handle of the property. + @param rValue the value to be converted + @return true if the value converted. + @throws css::lang::IllegalArgumentException + @throws css::beans::UnknownPropertyException + @throws css::uno::RuntimeException + */ + virtual bool convertFastPropertyValue(std::unique_lock<std::mutex>& rGuard, + css::uno::Any& rConvertedValue, css::uno::Any& rOldValue, + sal_Int32 nHandle, const css::uno::Any& rValue) + = 0; + + /** The same as setFastPropertyValue; nHandle is always valid. + The changes must not be broadcasted in this method. + The method is implemented in a derived class. + + @attention + Although you are permitted to throw any UNO exception, only the following + are valid for usage: + -- css::beans::UnknownPropertyException + -- css::beans::PropertyVetoException + -- css::lang::IllegalArgumentException + -- css::lang::WrappedTargetException + -- css::uno::RuntimeException + + @param nHandle + handle + @param rValue + value + @throws css::uno::Exception + */ + virtual void setFastPropertyValue_NoBroadcast(std::unique_lock<std::mutex>& rGuard, + sal_Int32 nHandle, const css::uno::Any& rValue) + = 0; + /** + The same as getFastPropertyValue, but return the value through rValue and nHandle + is always valid. + The method is not implemented in this class. + */ + virtual void getFastPropertyValue(std::unique_lock<std::mutex>& rGuard, css::uno::Any& rValue, + sal_Int32 nHandle) const = 0; + + /** sets an dependent property's value + + <p>Sometimes setting a given property needs to implicitly modify another property's value. Calling |setPropertyValue| + from within |setFastPropertyValue_NoBroadcast| is not an option here, as it would notify the property listeners + while our mutex is still locked. Setting the dependent property's value directly (e.g. by calling |setFastPropertyValue_NoBroadcast| + recursively) is not an option, too, since it would miss firing the property change event.</p> + + <p>So, in such cases, you use |setDependentFastPropertyValue| from within |setFastPropertyValue_NoBroadcast|. + It will convert and actually set the property value (invoking |convertFastPropertyValue| and |setFastPropertyValue_NoBroadcast| + for the given handle and value), and add the property change event to the list of events to be notified + when the bottom-most |setFastPropertyValue_NoBroadcast| on the stack returns.</p> + + <p><strong>Note</strong>: The method will <em>not</em> invoke veto listeners for the property.</p> + + <p><strong>Note</strong>: It's the caller's responsibility to ensure that our mutex is locked. This is + canonically given when the method is invoked from within |setFastPropertyValue_NoBroadcast|, in other + contexts, you might need to take own measures.</p> + */ + void setDependentFastPropertyValue(std::unique_lock<std::mutex>& rGuard, sal_Int32 i_handle, + const css::uno::Any& i_value); + +private: + /** + Container for the XPropertyChangedListener. The listeners are inserted by handle. + */ + OMultiTypeInterfaceContainerHelperVar4<sal_Int32, css::beans::XPropertyChangeListener> aBoundLC; + /** + Container for the XPropertyVetoableListener. The listeners are inserted by handle. + */ + OMultiTypeInterfaceContainerHelperVar4<sal_Int32, css::beans::XVetoableChangeListener> + aVetoableLC; + /** + Container for the XPropertyChangedListener where the listeners want to listen to all properties. + */ + comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener> + maPropertyChangeListeners; + comphelper::OInterfaceContainerHelper4<css::beans::XPropertiesChangeListener> + maPropertiesChangeListeners; + /** + Container for the XVetoableChangeListener where the listeners want to listen to all properties. + */ + comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener> + maVetoableChangeListeners; + cppu::IEventNotificationHook* const m_pFireEvents = nullptr; + std::vector<sal_Int32> m_handles; + std::vector<css::uno::Any> m_newValues; + std::vector<css::uno::Any> m_oldValues; + bool m_bIgnoreRuntimeExceptionsWhileFiring = false; + bool m_bFireEvents = true; + + /** notifies the given changes in property's values, <em>plus</em> all property changes collected during recent + |setDependentFastPropertyValue| calls. + */ + void impl_fireAll(std::unique_lock<std::mutex>& rGuard, sal_Int32* i_handles, + const css::uno::Any* i_newValues, const css::uno::Any* i_oldValues, + sal_Int32 i_count); + + void fireVetoableChangeListeners( + std::unique_lock<std::mutex>& rGuard, + comphelper::OInterfaceContainerHelper4<css::beans::XVetoableChangeListener>* pListeners, + const css::beans::PropertyChangeEvent& rChangeEvent); + void firePropertyChangeListeners( + std::unique_lock<std::mutex>& rGuard, + comphelper::OInterfaceContainerHelper4<css::beans::XPropertyChangeListener>* pListeners, + const css::beans::PropertyChangeEvent& rChangeEvent); +}; + +} // end namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/include/comphelper/unoimplbase.hxx b/include/comphelper/unoimplbase.hxx new file mode 100644 index 000000000000..a2d6803a09b5 --- /dev/null +++ b/include/comphelper/unoimplbase.hxx @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +#pragma once + +#include <comphelper/comphelperdllapi.h> +#include <mutex> + +namespace comphelper +{ +/** +This class is meant to be used as a base class for UNO object implementations that +want to use std::mutex for locking. +It meant to be virtually inherited, so the base class is shared between +the UNO object and helper classes like comphelper::OPropertySetHelper +*/ +class COMPHELPER_DLLPUBLIC UnoImplBase +{ +public: + virtual ~UnoImplBase(); + +protected: + mutable std::mutex m_aMutex; + bool m_bDisposed = false; +}; + +} // namespace comphelper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/include/toolkit/controls/unocontrolmodel.hxx b/include/toolkit/controls/unocontrolmodel.hxx index a3f0516e8157..a33d73b897bc 100644 --- a/include/toolkit/controls/unocontrolmodel.hxx +++ b/include/toolkit/controls/unocontrolmodel.hxx @@ -31,7 +31,7 @@ #include <comphelper/broadcasthelper.hxx> #include <toolkit/helper/listenermultiplexer.hxx> -#include <cppuhelper/propshlp.hxx> +#include <comphelper/propshlp.hxx> #include <cppuhelper/implbase6.hxx> #include <comphelper/uno3.hxx> #include <rtl/ref.hxx> @@ -43,9 +43,6 @@ namespace com::sun::star::uno { class XComponentContext; } typedef std::map<sal_uInt16, css::uno::Any> ImplPropertyTable; - - - typedef ::cppu::WeakAggImplHelper6 < css::awt::XControlModel , css::beans::XPropertyState , css::io::XPersistObject @@ -54,9 +51,8 @@ typedef ::cppu::WeakAggImplHelper6 < css::awt::XControlModel , css::util::XCloneable > UnoControlModel_Base; -class UnoControlModel :public UnoControlModel_Base - ,public comphelper::OMutexAndBroadcastHelper - ,public ::cppu::OPropertySetHelper +class UnoControlModel : public UnoControlModel_Base + ,public ::comphelper::OPropertySetHelper { private: ImplPropertyTable maData; @@ -105,7 +101,7 @@ protected: #ifdef _MSC_VER UnoControlModel() //do not use! needed by MSVC at compile time to satisfy WeakAggImplHelper7 : UnoControlModel_Base() - , OPropertySetHelper( m_aBHelper ) + , OPropertySetHelper() , maDisposeListeners( *this ) , m_xContext( css::uno::Reference< css::uno::XComponentContext >() ) { @@ -155,20 +151,25 @@ public: css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; // ::cppu::OPropertySetHelper - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override = 0; - sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any & rConvertedValue, css::uno::Any & rOldValue, sal_Int32 nHandle, const css::uno::Any& rValue ) override; - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; - using cppu::OPropertySetHelper::getFastPropertyValue; - void SAL_CALL getFastPropertyValue( css::uno::Any& rValue, sal_Int32 nHandle ) const override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override = 0; + bool convertFastPropertyValue( std::unique_lock<std::mutex>& rGuard, css::uno::Any & rConvertedValue, css::uno::Any & rOldValue, sal_Int32 nHandle, const css::uno::Any& rValue ) override; + void setFastPropertyValue_NoBroadcast( + std::unique_lock<std::mutex>& rGuard, + sal_Int32 nHandle, const css::uno::Any& rValue ) override; + using comphelper::OPropertySetHelper::getFastPropertyValue; + void getFastPropertyValue( std::unique_lock<std::mutex>& rGuard, css::uno::Any& rValue, sal_Int32 nHandle ) const override; - // override setValue methods to handle properties of FontDescriptor - // css::beans::XPropertySet - void SAL_CALL setPropertyValue( const OUString& aPropertyName, const css::uno::Any& aValue ) override; - // css::beans::XFastPropertySet - void SAL_CALL setFastPropertyValue( sal_Int32 nHandle, const css::uno::Any& aValue ) override; // css::beans::XMultiPropertySet css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; void SAL_CALL setPropertyValues( const css::uno::Sequence< OUString >& PropertyNames, const css::uno::Sequence< css::uno::Any >& Values ) override; +protected: + // override setValue methods to handle properties of FontDescriptor + // css::beans::XPropertySet + virtual void setPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, const OUString& aPropertyName, const css::uno::Any& aValue ) override; + // css::beans::XFastPropertySet + void setFastPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& aValue ) override; + css::beans::PropertyState getPropertyStateImpl( std::unique_lock<std::mutex>& rGuard, const OUString& PropertyName ); + void setPropertyValuesImpl( std::unique_lock<std::mutex>& rGuard, const css::uno::Sequence< OUString >& PropertyNames, const css::uno::Sequence< css::uno::Any >& Values ); }; #endif // INCLUDED_TOOLKIT_CONTROLS_UNOCONTROLMODEL_HXX diff --git a/include/toolkit/controls/unocontrols.hxx b/include/toolkit/controls/unocontrols.hxx index 121bdec42eb3..1fba20389a8b 100644 --- a/include/toolkit/controls/unocontrols.hxx +++ b/include/toolkit/controls/unocontrols.hxx @@ -49,7 +49,7 @@ #include <cppuhelper/implbase5.hxx> #include <cppuhelper/implbase4.hxx> #include <cppuhelper/implbase1.hxx> -#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/interfacecontainer4.hxx> #include <comphelper/uno3.hxx> #include <tools/gen.hxx> @@ -79,7 +79,7 @@ public: class UnoControlEditModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlEditModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -182,7 +182,7 @@ public: class UnoControlFileControlModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlFileControlModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -233,8 +233,8 @@ protected: } GraphicControlModel( const GraphicControlModel& _rSource ) : UnoControlModel( _rSource ), mbAdjustingImagePosition( false ), mbAdjustingGraphic( false ) { } - // ::cppu::OPropertySetHelper - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + // ::comphelper::OPropertySetHelper + void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; // UnoControlModel css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; @@ -248,7 +248,7 @@ private: class UnoControlButtonModel final : public GraphicControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlButtonModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -327,7 +327,7 @@ private: bool mbAdjustingImageScaleMode; css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlImageControlModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -347,7 +347,7 @@ public: css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; // ::cppu::OPropertySetHelper - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; }; @@ -386,7 +386,7 @@ public: class UnoControlRadioButtonModel final : public GraphicControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlRadioButtonModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -464,7 +464,7 @@ public: class UnoControlCheckBoxModel final : public GraphicControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlCheckBoxModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -544,7 +544,7 @@ public: class UnoControlFixedHyperlinkModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlFixedHyperlinkModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -615,7 +615,7 @@ public: class UnoControlFixedTextModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlFixedTextModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -679,7 +679,7 @@ public: class UnoControlGroupBoxModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlGroupBoxModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -777,14 +777,15 @@ public: virtual void SAL_CALL removeItemListListener( const css::uno::Reference< css::awt::XItemListListener >& Listener ) override; // OPropertySetHelper - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; protected: css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; private: - void impl_notifyItemListEvent_nolck( + void impl_notifyItemListEvent( + std::unique_lock<std::mutex>& rGuard, const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, const ::std::optional< OUString >& i_rItemImageURL, @@ -792,30 +793,30 @@ private: ); void impl_handleInsert( + std::unique_lock<std::mutex>& rGuard, const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, - const ::std::optional< OUString >& i_rItemImageURL, - ::osl::ClearableMutexGuard& i_rClearBeforeNotify + const ::std::optional< OUString >& i_rItemImageURL ); void impl_handleRemove( const sal_Int32 i_nItemPosition, - ::osl::ClearableMutexGuard& i_rClearBeforeNotify + std::unique_lock<std::mutex>& i_rClearBeforeNotify ); void impl_handleModify( const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, const ::std::optional< OUString >& i_rItemImageURL, - ::osl::ClearableMutexGuard& i_rClearBeforeNotify + std::unique_lock<std::mutex>& i_rClearBeforeNotify ); - void impl_getStringItemList( ::std::vector< OUString >& o_rStringItems ) const; - void impl_setStringItemList_nolck( const ::std::vector< OUString >& i_rStringItems ); + void impl_getStringItemList( std::unique_lock<std::mutex>& rGuard, ::std::vector< OUString >& o_rStringItems ) const; + void impl_setStringItemList( std::unique_lock<std::mutex>& rGuard, const ::std::vector< OUString >& i_rStringItems ); protected: std::unique_ptr<UnoControlListBoxModel_Data> m_xData; - ::comphelper::OInterfaceContainerHelper3<css::awt::XItemListListener> m_aItemListListeners; + ::comphelper::OInterfaceContainerHelper4<css::awt::XItemListListener> m_aItemListListeners; }; @@ -901,7 +902,7 @@ private: class UnoControlComboBoxModel final : public UnoControlListBoxModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlComboBoxModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -915,7 +916,7 @@ public: // css::beans::XMultiPropertySet css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; // OPropertySetHelper - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; // css::lang::XServiceInfo OUString SAL_CALL getImplementationName( ) override; @@ -1031,7 +1032,7 @@ public: class UnoControlDateFieldModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlDateFieldModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -1107,7 +1108,7 @@ public: class UnoControlTimeFieldModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlTimeFieldModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -1181,7 +1182,7 @@ public: class UnoControlNumericFieldModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlNumericFieldModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -1257,7 +1258,7 @@ public: class UnoControlCurrencyFieldModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlCurrencyFieldModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -1333,7 +1334,7 @@ public: class UnoControlPatternFieldModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlPatternFieldModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -1392,7 +1393,7 @@ public: class UnoControlProgressBarModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlProgressBarModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); @@ -1448,7 +1449,7 @@ public: class UnoControlFixedLineModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlFixedLineModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); diff --git a/include/toolkit/helper/listenermultiplexer.hxx b/include/toolkit/helper/listenermultiplexer.hxx index f2d9db4e625d..b7113c17ee64 100644 --- a/include/toolkit/helper/listenermultiplexer.hxx +++ b/include/toolkit/helper/listenermultiplexer.hxx @@ -100,6 +100,11 @@ public: maListeners.disposeAndClear(g, rDisposeEvent); } + void disposeAndClear(std::unique_lock<std::mutex>& rGuard, const css::lang::EventObject& rDisposeEvent) + { + maListeners.disposeAndClear(rGuard, rDisposeEvent); + } + sal_Int32 getLength() const { std::unique_lock g(m_aMutex); diff --git a/toolkit/inc/controls/animatedimages.hxx b/toolkit/inc/controls/animatedimages.hxx index a341447c5366..fca49bfa39de 100644 --- a/toolkit/inc/controls/animatedimages.hxx +++ b/toolkit/inc/controls/animatedimages.hxx @@ -72,10 +72,13 @@ namespace toolkit virtual ~AnimatedImagesControlModel() override; css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; + void setFastPropertyValue_NoBroadcast( + std::unique_lock<std::mutex>& rGuard, + sal_Int32 nHandle, const css::uno::Any& rValue ) override; private: + comphelper::OInterfaceContainerHelper4<css::container::XContainerListener> maContainerListeners; std::vector< css::uno::Sequence< OUString > > maImageSets; }; diff --git a/toolkit/inc/controls/controlmodelcontainerbase.hxx b/toolkit/inc/controls/controlmodelcontainerbase.hxx index 1bbc3f301b16..ae414346c78f 100644 --- a/toolkit/inc/controls/controlmodelcontainerbase.hxx +++ b/toolkit/inc/controls/controlmodelcontainerbase.hxx @@ -36,7 +36,7 @@ #include <cppuhelper/propshlp.hxx> #include <com/sun/star/awt/tab/XTabPageModel.hpp> #include <com/sun/star/lang/XInitialization.hpp> -#include <comphelper/interfacecontainer3.hxx> +#include <comphelper/interfacecontainer4.hxx> #include <mutex> #include <vector> @@ -78,7 +78,7 @@ public: protected: ContainerListenerMultiplexer maContainerListeners; - ::comphelper::OInterfaceContainerHelper3<css::util::XChangesListener> maChangeListeners; + ::comphelper::OInterfaceContainerHelper4<css::util::XChangesListener> maChangeListeners; UnoControlModelHolderVector maModels; AllGroups maGroups; @@ -91,7 +91,7 @@ protected: void Clone_Impl(ControlModelContainerBase& _rClone) const; protected: css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; UnoControlModelHolderVector::iterator ImplFindElement( std::u16string_view rName ); @@ -152,7 +152,7 @@ public: virtual void SAL_CALL propertyChange( const css::beans::PropertyChangeEvent& evt ) override; // XEventListener - using cppu::OPropertySetHelper::disposing; + using comphelper::OPropertySetHelper::disposing; virtual void SAL_CALL disposing( const css::lang::EventObject& evt ) override; // XServiceInfo diff --git a/toolkit/inc/controls/dialogcontrol.hxx b/toolkit/inc/controls/dialogcontrol.hxx index b23c60f445f5..3aaf3e50b135 100644 --- a/toolkit/inc/controls/dialogcontrol.hxx +++ b/toolkit/inc/controls/dialogcontrol.hxx @@ -160,13 +160,9 @@ class UnoMultiPageModel final : public ControlModelContainerBase { public: UnoMultiPageModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + UnoMultiPageModel(const UnoMultiPageModel& rOther) : ControlModelContainerBase(rOther) {} virtual ~UnoMultiPageModel() override; - UnoMultiPageModel(UnoMultiPageModel const &) = default; - UnoMultiPageModel(UnoMultiPageModel &&) = default; - UnoMultiPageModel & operator =(UnoMultiPageModel const &) = delete; // due to ControlModelContainerBase - UnoMultiPageModel & operator =(UnoMultiPageModel &&) = delete; // due to ControlModelContainerBase - rtl::Reference<UnoControlModel> Clone() const override; DECLIMPL_SERVICEINFO_DERIVED( UnoMultiPageModel, ControlModelContainerBase, "com.sun.star.awt.UnoMultiPageModel" ) @@ -180,7 +176,7 @@ public: virtual sal_Bool SAL_CALL getGroupControl( ) override; private: virtual css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; }; @@ -239,13 +235,9 @@ class UnoPageModel final : public ControlModelContainerBase { public: UnoPageModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + UnoPageModel(const UnoPageModel& rOther) : ControlModelContainerBase(rOther) {} virtual ~UnoPageModel() override; - UnoPageModel(UnoPageModel const &) = default; - UnoPageModel(UnoPageModel &&) = default; - UnoPageModel & operator =(UnoPageModel const &) = delete; // due to ControlModelContainerBase - UnoPageModel & operator =(UnoPageModel &&) = delete; // due to ControlModelContainerBase - rtl::Reference<UnoControlModel> Clone() const override; DECLIMPL_SERVICEINFO_DERIVED( UnoPageModel, ControlModelContainerBase, "com.sun.star.awt.UnoPageModel" ) @@ -257,7 +249,7 @@ public: virtual sal_Bool SAL_CALL getGroupControl( ) override; private: virtual css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; }; @@ -277,13 +269,9 @@ class UnoFrameModel final : public ControlModelContainerBase { public: UnoFrameModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + UnoFrameModel(const UnoFrameModel& rOther) : ControlModelContainerBase(rOther) {} virtual ~UnoFrameModel() override; - UnoFrameModel(UnoFrameModel const &) = default; - UnoFrameModel(UnoFrameModel &&) = default; - UnoFrameModel & operator =(UnoFrameModel const &) = delete; // due to ControlModelContainerBase - UnoFrameModel & operator =(UnoFrameModel &&) = delete; // due to ControlModelContainerBase - rtl::Reference<UnoControlModel> Clone() const override; DECLIMPL_SERVICEINFO_DERIVED( UnoFrameModel, ControlModelContainerBase, "com.sun.star.awt.UnoFrameModel" ) @@ -293,7 +281,7 @@ public: private: virtual css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; }; class UnoFrameControl final : public ControlContainerBase diff --git a/toolkit/inc/controls/formattedcontrol.hxx b/toolkit/inc/controls/formattedcontrol.hxx index 388d94312aab..c614b42c74d3 100644 --- a/toolkit/inc/controls/formattedcontrol.hxx +++ b/toolkit/inc/controls/formattedcontrol.hxx @@ -72,20 +72,22 @@ namespace toolkit css::uno::Any* _pValues, /// the values of the properties to set sal_Int32* _pValidHandles /// pointer to the valid handles, allowed to be adjusted ) const override; - void impl_updateTextFromValue_nothrow(); - void impl_updateCachedFormatter_nothrow(); - void impl_updateCachedFormatKey_nothrow(); + void impl_updateTextFromValue_nothrow(std::unique_lock<std::mutex>& rGuard); + void impl_updateCachedFormatter_nothrow(std::unique_lock<std::mutex>& rGuard); + void impl_updateCachedFormatKey_nothrow(std::unique_lock<std::mutex>& rGuard); css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; - sal_Bool SAL_CALL convertFastPropertyValue( + ::cppu::IPropertyArrayHelper& getInfoHelper() override; + bool convertFastPropertyValue( + std::unique_lock<std::mutex>& rGuard, css::uno::Any& rConvertedValue, css::uno::Any& rOldValue, sal_Int32 nPropId, const css::uno::Any& rValue ) override; - void SAL_CALL setFastPropertyValue_NoBroadcast( + void setFastPropertyValue_NoBroadcast( + std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; diff --git a/toolkit/inc/controls/roadmapcontrol.hxx b/toolkit/inc/controls/roadmapcontrol.hxx index cfc7fbdb9c74..cb6e2cec4533 100644 --- a/toolkit/inc/controls/roadmapcontrol.hxx +++ b/toolkit/inc/controls/roadmapcontrol.hxx @@ -83,7 +83,7 @@ namespace toolkit sal_Int32 GetUniqueID(); css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlRoadmapModel( const css::uno::Reference< css::uno::XComponentContext >& i_factory ); diff --git a/toolkit/inc/controls/tabpagecontainer.hxx b/toolkit/inc/controls/tabpagecontainer.hxx index d8cc32664406..f9fe2df02d50 100644 --- a/toolkit/inc/controls/tabpagecontainer.hxx +++ b/toolkit/inc/controls/tabpagecontainer.hxx @@ -43,7 +43,7 @@ private: ContainerListenerMultiplexer maContainerListeners; css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; // css::beans::XMultiPropertySet css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) override; diff --git a/toolkit/inc/controls/tabpagemodel.hxx b/toolkit/inc/controls/tabpagemodel.hxx index 6c12981b28e9..48a84fe5a602 100644 --- a/toolkit/inc/controls/tabpagemodel.hxx +++ b/toolkit/inc/controls/tabpagemodel.hxx @@ -26,7 +26,7 @@ class UnoControlTabPageModel final : public ControlModelContainerBase { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlTabPageModel( css::uno::Reference< css::uno::XComponentContext > const & i_factory); diff --git a/toolkit/inc/controls/tkscrollbar.hxx b/toolkit/inc/controls/tkscrollbar.hxx index ec774fa9dfb3..c7948de072e5 100644 --- a/toolkit/inc/controls/tkscrollbar.hxx +++ b/toolkit/inc/controls/tkscrollbar.hxx @@ -33,7 +33,7 @@ namespace toolkit class UnoControlScrollBarModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlScrollBarModel( const css::uno::Reference< css::uno::XComponentContext >& i_factory ); diff --git a/toolkit/inc/controls/unocontrolcontainermodel.hxx b/toolkit/inc/controls/unocontrolcontainermodel.hxx index 4fe48cdcab6f..83db8af31b7c 100644 --- a/toolkit/inc/controls/unocontrolcontainermodel.hxx +++ b/toolkit/inc/controls/unocontrolcontainermodel.hxx @@ -27,7 +27,7 @@ class UnoControlContainerModel final : public UnoControlModel { css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: UnoControlContainerModel( const css::uno::Reference< css::uno::XComponentContext >& i_factory ); diff --git a/toolkit/source/controls/animatedimages.cxx b/toolkit/source/controls/animatedimages.cxx index d188ab20960b..5d8267998496 100644 --- a/toolkit/source/controls/animatedimages.cxx +++ b/toolkit/source/controls/animatedimages.cxx @@ -211,12 +211,11 @@ namespace toolkit { throw IndexOutOfBoundsException( OUString(), i_context ); } - void lcl_notify( ::osl::ClearableMutexGuard& i_guard, ::cppu::OBroadcastHelper const & i_broadcaseHelper, + void lcl_notify( std::unique_lock<std::mutex>& i_guard, comphelper::OInterfaceContainerHelper4<XContainerListener>& rContainer, void ( SAL_CALL XContainerListener::*i_notificationMethod )( const ContainerEvent& ), const sal_Int32 i_accessor, const Sequence< OUString >& i_imageURLs, const Reference< XInterface >& i_context ) { - ::cppu::OInterfaceContainerHelper* pContainerListeners = i_broadcaseHelper.getContainer( cppu::UnoType<XContainerListener>::get() ); - if ( pContainerListeners == nullptr ) + if ( !rContainer.getLength(i_guard) ) return; ContainerEvent aEvent; @@ -224,8 +223,7 @@ namespace toolkit { aEvent.Accessor <<= i_accessor; aEvent.Element <<= i_imageURLs; - i_guard.clear(); - pContainerListeners->notifyEach( i_notificationMethod, aEvent ); + rContainer.notifyEach( i_guard, i_notificationMethod, aEvent ); } } @@ -289,7 +287,7 @@ namespace toolkit { } - void SAL_CALL AnimatedImagesControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 i_handle, const Any& i_value ) + void AnimatedImagesControlModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 i_handle, const Any& i_value ) { switch ( i_handle ) { @@ -306,7 +304,7 @@ namespace toolkit { break; } - AnimatedImagesControlModel_Base::setFastPropertyValue_NoBroadcast( i_handle, i_value ); + AnimatedImagesControlModel_Base::setFastPropertyValue_NoBroadcast( rGuard, i_handle, i_value ); } @@ -335,7 +333,7 @@ namespace toolkit { } - ::cppu::IPropertyArrayHelper& SAL_CALL AnimatedImagesControlModel::getInfoHelper() + ::cppu::IPropertyArrayHelper& AnimatedImagesControlModel::getInfoHelper() { static UnoPropertyArrayHelper aHelper( ImplGetPropertyIds() ); return aHelper; @@ -386,8 +384,8 @@ namespace toolkit { ::sal_Int32 SAL_CALL AnimatedImagesControlModel::getImageSetCount( ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); - if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + std::unique_lock aGuard( m_aMutex ); + if ( m_bDisposed ) throw DisposedException(); return maImageSets.size(); @@ -396,8 +394,8 @@ namespace toolkit { Sequence< OUString > SAL_CALL AnimatedImagesControlModel::getImageSet( ::sal_Int32 i_index ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); - if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + std::unique_lock aGuard( m_aMutex ); + if ( m_bDisposed ) throw DisposedException(); lcl_checkIndex( maImageSets, i_index, *this ); @@ -408,9 +406,9 @@ namespace toolkit { void SAL_CALL AnimatedImagesControlModel::insertImageSet( ::sal_Int32 i_index, const Sequence< OUString >& i_imageURLs ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // sanity checks - if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + if ( m_bDisposed ) throw DisposedException(); lcl_checkIndex( maImageSets, i_index, *this, true ); @@ -419,15 +417,15 @@ namespace toolkit { maImageSets.insert( maImageSets.begin() + i_index, i_imageURLs ); // listener notification - lcl_notify( aGuard, m_aBHelper, &XContainerListener::elementInserted, i_index, i_imageURLs, *this ); + lcl_notify( aGuard, maContainerListeners, &XContainerListener::elementInserted, i_index, i_imageURLs, *this ); } void SAL_CALL AnimatedImagesControlModel::replaceImageSet( ::sal_Int32 i_index, const Sequence< OUString >& i_imageURLs ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // sanity checks - if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + if ( m_bDisposed ) throw DisposedException(); lcl_checkIndex( maImageSets, i_index, *this ); @@ -436,15 +434,15 @@ namespace toolkit { maImageSets[ i_index ] = i_imageURLs; // listener notification - lcl_notify( aGuard, m_aBHelper, &XContainerListener::elementReplaced, i_index, i_imageURLs, *this ); + lcl_notify( aGuard, maContainerListeners, &XContainerListener::elementReplaced, i_index, i_imageURLs, *this ); } void SAL_CALL AnimatedImagesControlModel::removeImageSet( ::sal_Int32 i_index ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // sanity checks - if ( GetBroadcastHelper().bDisposed || GetBroadcastHelper().bInDispose ) + if ( m_bDisposed ) throw DisposedException(); lcl_checkIndex( maImageSets, i_index, *this ); @@ -455,19 +453,21 @@ namespace toolkit { maImageSets.erase( removalPos ); // listener notification - lcl_notify( aGuard, m_aBHelper, &XContainerListener::elementRemoved, i_index, aRemovedElement, *this ); + lcl_notify( aGuard, maContainerListeners, &XContainerListener::elementRemoved, i_index, aRemovedElement, *this ); } void SAL_CALL AnimatedImagesControlModel::addContainerListener( const Reference< XContainerListener >& i_listener ) { - m_aBHelper.addListener( cppu::UnoType<XContainerListener>::get(), i_listener ); + std::unique_lock aGuard( m_aMutex ); + maContainerListeners.addInterface( aGuard, i_listener ); } void SAL_CALL AnimatedImagesControlModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) { - m_aBHelper.removeListener( cppu::UnoType<XContainerListener>::get(), i_listener ); + std::unique_lock aGuard( m_aMutex ); + maContainerListeners.removeInterface( aGuard, i_listener ); } } diff --git a/toolkit/source/controls/controlmodelcontainerbase.cxx b/toolkit/source/controls/controlmodelcontainerbase.cxx index b0b37df4cbf7..bec15994a034 100644 --- a/toolkit/source/controls/controlmodelcontainerbase.cxx +++ b/toolkit/source/controls/controlmodelcontainerbase.cxx @@ -168,7 +168,6 @@ static OUString getStepPropertyName( ) ControlModelContainerBase::ControlModelContainerBase( const Reference< XComponentContext >& rxContext ) :ControlModelContainer_IBase( rxContext ) ,maContainerListeners( *this ) - ,maChangeListeners ( GetMutex() ) ,mbGroupsUpToDate( false ) ,m_nTabPageId(0) { @@ -178,7 +177,6 @@ ControlModelContainerBase::ControlModelContainerBase( const Reference< XComponen ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel ) : ControlModelContainer_IBase( rModel ) , maContainerListeners( *this ) - , maChangeListeners ( GetMutex() ) , mbGroupsUpToDate( false ) , m_nTabPageId( rModel.m_nTabPageId ) { @@ -217,13 +215,13 @@ void SAL_CALL ControlModelContainerBase::dispose( ) // tell our listeners { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); EventObject aDisposeEvent; aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) ); - maContainerListeners.disposeAndClear( aDisposeEvent ); - maChangeListeners.disposeAndClear( aDisposeEvent ); + maContainerListeners.disposeAndClear( aGuard, aDisposeEvent ); + maChangeListeners.disposeAndClear( aGuard, aDisposeEvent ); } @@ -848,13 +846,15 @@ void SAL_CALL ControlModelContainerBase::getGroupByName( const OUString& _rName, void SAL_CALL ControlModelContainerBase::addChangesListener( const Reference< XChangesListener >& _rxListener ) { - maChangeListeners.addInterface( _rxListener ); + std::unique_lock g(m_aMutex); + maChangeListeners.addInterface( g, _rxListener ); } void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener ) { - maChangeListeners.removeInterface( _rxListener ); + std::unique_lock g(m_aMutex); + maChangeListeners.removeInterface( g, _rxListener ); } @@ -869,7 +869,9 @@ void ControlModelContainerBase::implNotifyTabModelChange( const OUString& _rAcce aEvent.Changes.getArray()[ 0 ].Accessor <<= _rAccessor; - std::vector< Reference< css::util::XChangesListener > > aChangeListeners( maChangeListeners.getElements() ); + std::unique_lock g(m_aMutex); + std::vector< Reference< css::util::XChangesListener > > aChangeListeners( maChangeListeners.getElements(g) ); + g.unlock(); for ( const auto& rListener : aChangeListeners ) rListener->changesOccurred( aEvent ); } diff --git a/toolkit/source/controls/dialogcontrol.cxx b/toolkit/source/controls/dialogcontrol.cxx index 67ee3bcc6719..b9027cbf17d7 100644 --- a/toolkit/source/controls/dialogcontrol.cxx +++ b/toolkit/source/controls/dialogcontrol.cxx @@ -137,9 +137,9 @@ class UnoControlDialogModel : public ControlModelContainerBase protected: css::uno::Reference< css::graphic::XGraphicObject > mxGrfObj; css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; - // ::cppu::OPropertySetHelper - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; + // ::comphelper::OPropertySetHelper + void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; public: explicit UnoControlDialogModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext ); UnoControlDialogModel( const UnoControlDialogModel& rModel ); @@ -213,7 +213,8 @@ UnoControlDialogModel::UnoControlDialogModel( const UnoControlDialogModel& rMode if ( xSrcNameCont->hasByName( name ) ) xNameCont->insertByName( name, xSrcNameCont->getByName( name ) ); } - setFastPropertyValue_NoBroadcast( BASEPROPERTY_USERFORMCONTAINEES, Any( xNameCont ) ); + std::unique_lock aGuard(m_aMutex); + setFastPropertyValue_NoBroadcast( aGuard, BASEPROPERTY_USERFORMCONTAINEES, Any( xNameCont ) ); } rtl::Reference<UnoControlModel> UnoControlDialogModel::Clone() const @@ -267,9 +268,9 @@ Reference< XPropertySetInfo > UnoControlDialogModel::getPropertySetInfo( ) return xInfo; } -void SAL_CALL UnoControlDialogModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) +void UnoControlDialogModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) { - ControlModelContainerBase::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + ControlModelContainerBase::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue ); try { if ( nHandle == BASEPROPERTY_IMAGEURL && ImplHasProperty( BASEPROPERTY_GRAPHIC ) ) @@ -278,14 +279,14 @@ void SAL_CALL UnoControlDialogModel::setFastPropertyValue_NoBroadcast( sal_Int32 uno::Reference<graphic::XGraphic> xGraphic; if (rValue >>= sImageURL) { - setPropertyValue( + setPropertyValueImpl(rGuard, GetPropertyName(BASEPROPERTY_GRAPHIC), uno::Any(ImageHelper::getGraphicAndGraphicObjectFromURL_nothrow( mxGrfObj, sImageURL))); } else if (rValue >>= xGraphic) { - setPropertyValue("Graphic", uno::Any(xGraphic)); + setPropertyValueImpl(rGuard, "Graphic", uno::Any(xGraphic)); } } } diff --git a/toolkit/source/controls/formattedcontrol.cxx b/toolkit/source/controls/formattedcontrol.cxx index e96a6986a7d0..ff34f4cbdda7 100644 --- a/toolkit/source/controls/formattedcontrol.cxx +++ b/toolkit/source/controls/formattedcontrol.cxx @@ -154,39 +154,39 @@ namespace toolkit } - void SAL_CALL UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) + void UnoControlFormattedFieldModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const Any& rValue ) { - UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue ); switch ( nHandle ) { case BASEPROPERTY_EFFECTIVE_VALUE: if ( !m_bSettingValueAndText ) - impl_updateTextFromValue_nothrow(); + impl_updateTextFromValue_nothrow(rGuard); break; case BASEPROPERTY_FORMATSSUPPLIER: - impl_updateCachedFormatter_nothrow(); - impl_updateTextFromValue_nothrow(); + impl_updateCachedFormatter_nothrow(rGuard); + impl_updateTextFromValue_nothrow(rGuard); break; case BASEPROPERTY_FORMATKEY: - impl_updateCachedFormatKey_nothrow(); - impl_updateTextFromValue_nothrow(); + impl_updateCachedFormatKey_nothrow(rGuard); + impl_updateTextFromValue_nothrow(rGuard); break; } } - void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow() + void UnoControlFormattedFieldModel::impl_updateTextFromValue_nothrow( std::unique_lock<std::mutex>& rGuard) { if ( !m_xCachedFormatter.is() ) - impl_updateCachedFormatter_nothrow(); + impl_updateCachedFormatter_nothrow(rGuard); if ( !m_xCachedFormatter.is() ) return; try { Any aEffectiveValue; - getFastPropertyValue( aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE ); + getFastPropertyValue( rGuard, aEffectiveValue, BASEPROPERTY_EFFECTIVE_VALUE ); OUString sStringValue; if ( !( aEffectiveValue >>= sStringValue ) ) @@ -201,7 +201,7 @@ namespace toolkit } } - setPropertyValue( GetPropertyName( BASEPROPERTY_TEXT ), Any( sStringValue ) ); + setPropertyValueImpl( rGuard, GetPropertyName( BASEPROPERTY_TEXT ), Any( sStringValue ) ); } catch( const Exception& ) { @@ -210,10 +210,10 @@ namespace toolkit } - void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow() + void UnoControlFormattedFieldModel::impl_updateCachedFormatter_nothrow(std::unique_lock<std::mutex>& rGuard) { Any aFormatsSupplier; - getFastPropertyValue( aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER ); + getFastPropertyValue( rGuard, aFormatsSupplier, BASEPROPERTY_FORMATSSUPPLIER ); try { Reference< XNumberFormatsSupplier > xSupplier( aFormatsSupplier, UNO_QUERY ); @@ -236,10 +236,10 @@ namespace toolkit } - void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow() + void UnoControlFormattedFieldModel::impl_updateCachedFormatKey_nothrow(std::unique_lock<std::mutex>& rGuard) { Any aFormatKey; - getFastPropertyValue( aFormatKey, BASEPROPERTY_FORMATKEY ); + getFastPropertyValue( rGuard, aFormatKey, BASEPROPERTY_FORMATKEY ); m_aCachedFormat = aFormatKey; } @@ -248,7 +248,7 @@ namespace toolkit { UnoControlModel::dispose(); - ::osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); if ( !m_bRevokedAsClient ) { lcl_revokeDefaultFormatsClient(); @@ -305,7 +305,8 @@ namespace toolkit } - sal_Bool UnoControlFormattedFieldModel::convertFastPropertyValue( + bool UnoControlFormattedFieldModel::convertFastPropertyValue( + std::unique_lock<std::mutex>& rGuard, Any& rConvertedValue, Any& rOldValue, sal_Int32 nPropId, const Any& rValue ) { @@ -338,7 +339,7 @@ namespace toolkit if ( bStreamed ) { - getFastPropertyValue( rOldValue, nPropId ); + getFastPropertyValue( rGuard, rOldValue, nPropId ); return !CompareProperties( rConvertedValue, rOldValue ); } @@ -350,7 +351,7 @@ namespace toolkit 1); } - return UnoControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nPropId, rValue ); + return UnoControlModel::convertFastPropertyValue( rGuard, rConvertedValue, rOldValue, nPropId, rValue ); } diff --git a/toolkit/source/controls/grid/gridcontrol.cxx b/toolkit/source/controls/grid/gridcontrol.cxx index 106e704067aa..d6071046afc8 100644 --- a/toolkit/source/controls/grid/gridcontrol.cxx +++ b/toolkit/source/controls/grid/gridcontrol.cxx @@ -130,7 +130,8 @@ UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) } if ( !xDataModel.is() ) xDataModel = lcl_getDefaultDataModel_throw( m_xContext ); - UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_DATAMODEL, Any( xDataModel ) ); + std::unique_lock aGuard(m_aMutex); + UnoControlModel::setFastPropertyValue_NoBroadcast( aGuard, BASEPROPERTY_GRID_DATAMODEL, Any( xDataModel ) ); // do *not* use setFastPropertyValue here: The UnoControlModel ctor made a simple copy of all property values, // so before this call here, we share our data model with the own of the clone source. setFastPropertyValue, // then, disposes the old data model - which means the data model which in fact belongs to the clone source. @@ -149,7 +150,7 @@ UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) } if ( !xColumnModel.is() ) xColumnModel = lcl_getDefaultColumnModel_throw( m_xContext ); - UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_COLUMNMODEL, Any( xColumnModel ) ); + UnoControlModel::setFastPropertyValue_NoBroadcast( aGuard, BASEPROPERTY_GRID_COLUMNMODEL, Any( xColumnModel ) ); // same comment as above: do not use our own setPropertyValue here. } osl_atomic_decrement( &m_refCount ); @@ -188,12 +189,12 @@ void SAL_CALL UnoGridModel::dispose( ) } -void SAL_CALL UnoGridModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) +void UnoGridModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const Any& rValue ) { Any aOldSubModel; if ( ( nHandle == BASEPROPERTY_GRID_COLUMNMODEL ) || ( nHandle == BASEPROPERTY_GRID_DATAMODEL ) ) { - aOldSubModel = getFastPropertyValue( nHandle ); + getFastPropertyValue( rGuard, aOldSubModel, nHandle ); if ( aOldSubModel == rValue ) { OSL_ENSURE( false, "UnoGridModel::setFastPropertyValue_NoBroadcast: setting the same value, again!" ); @@ -202,7 +203,7 @@ void SAL_CALL UnoGridModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, } } - UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue ); if ( aOldSubModel.hasValue() ) lcl_dispose_nothrow( aOldSubModel ); diff --git a/toolkit/source/controls/grid/gridcontrol.hxx b/toolkit/source/controls/grid/gridcontrol.hxx index 435ff2fab089..9b7eae0eaa25 100644 --- a/toolkit/source/controls/grid/gridcontrol.hxx +++ b/toolkit/source/controls/grid/gridcontrol.hxx @@ -42,7 +42,7 @@ class UnoGridModel : public UnoControlModel { protected: css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: explicit UnoGridModel( const css::uno::Reference< css::uno::XComponentContext >& i_factory ); @@ -60,7 +60,7 @@ public: OUString SAL_CALL getServiceName() override; // OPropertySetHelper - void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) override; + void setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) override; // XServiceInfo OUString SAL_CALL getImplementationName() override diff --git a/toolkit/source/controls/spinningprogress.cxx b/toolkit/source/controls/spinningprogress.cxx index 7acac58e5565..851d624a3dd2 100644 --- a/toolkit/source/controls/spinningprogress.cxx +++ b/toolkit/source/controls/spinningprogress.cxx @@ -32,11 +32,7 @@ class SpinningProgressControlModel : public SpinningProgressControlModel_Base { public: explicit SpinningProgressControlModel( css::uno::Reference< css::uno::XComponentContext > const & i_factory ); - - SpinningProgressControlModel(SpinningProgressControlModel const &) = default; - SpinningProgressControlModel(SpinningProgressControlModel &&) = default; - SpinningProgressControlModel & operator =(SpinningProgressControlModel const &) = delete; // due to SpinningProgressControlModel_Base - SpinningProgressControlModel & operator =(SpinningProgressControlModel &&) = delete; // due to SpinningProgressControlModel_Base + SpinningProgressControlModel(const SpinningProgressControlModel& rOther) : SpinningProgressControlModel_Base(rOther) {} virtual rtl::Reference<UnoControlModel> Clone() const override; diff --git a/toolkit/source/controls/tabpagecontainer.cxx b/toolkit/source/controls/tabpagecontainer.cxx index 953c6b075cdf..82c24fdb0681 100644 --- a/toolkit/source/controls/tabpagecontainer.cxx +++ b/toolkit/source/controls/tabpagecontainer.cxx @@ -170,13 +170,13 @@ void SAL_CALL UnoControlTabPageContainerModel::replaceByIndex( ::sal_Int32 /*Ind // XIndexAccess ::sal_Int32 SAL_CALL UnoControlTabPageContainerModel::getCount( ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); return sal_Int32( m_aTabPageVector.size()); } uno::Any SAL_CALL UnoControlTabPageContainerModel::getByIndex( ::sal_Int32 nIndex ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); if ( nIndex < 0 || o3tl::make_unsigned(nIndex) > m_aTabPageVector.size() ) throw lang::IndexOutOfBoundsException(); return uno::Any(m_aTabPageVector[nIndex]); @@ -190,7 +190,7 @@ uno::Type SAL_CALL UnoControlTabPageContainerModel::getElementType( ) sal_Bool SAL_CALL UnoControlTabPageContainerModel::hasElements( ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); return !m_aTabPageVector.empty(); } // XContainer diff --git a/toolkit/source/controls/tkspinbutton.cxx b/toolkit/source/controls/tkspinbutton.cxx index 2040f668859b..9b106ed3a5d6 100644 --- a/toolkit/source/controls/tkspinbutton.cxx +++ b/toolkit/source/controls/tkspinbutton.cxx @@ -41,10 +41,11 @@ class UnoSpinButtonModel : public UnoControlModel { protected: css::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: explicit UnoSpinButtonModel( const css::uno::Reference< css::uno::XComponentContext >& i_factory ); + UnoSpinButtonModel(const UnoSpinButtonModel & rOther) : UnoControlModel(rOther) {} rtl::Reference<UnoControlModel> Clone() const override { return new UnoSpinButtonModel( *this ); } diff --git a/toolkit/source/controls/tree/treecontrol.hxx b/toolkit/source/controls/tree/treecontrol.hxx index af4793fe91ec..357afddb0f20 100644 --- a/toolkit/source/controls/tree/treecontrol.hxx +++ b/toolkit/source/controls/tree/treecontrol.hxx @@ -30,10 +30,14 @@ class UnoTreeModel : public UnoControlModel { protected: css::uno::Any ImplGetDefaultValue(sal_uInt16 nPropId) const override; - ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override; + ::cppu::IPropertyArrayHelper& getInfoHelper() override; public: explicit UnoTreeModel(const css::uno::Reference<css::uno::XComponentContext>& i_factory); + UnoTreeModel(const UnoTreeModel& rOther) + : UnoControlModel(rOther) + { + } rtl::Reference<UnoControlModel> Clone() const override; diff --git a/toolkit/source/controls/unocontrolmodel.cxx b/toolkit/source/controls/unocontrolmodel.cxx index 5b68774b678e..a881d2781b1e 100644 --- a/toolkit/source/controls/unocontrolmodel.cxx +++ b/toolkit/source/controls/unocontrolmodel.cxx @@ -110,7 +110,6 @@ static void lcl_ImplMergeFontProperty( FontDescriptor& rFD, sal_uInt16 nPropId, UnoControlModel::UnoControlModel( const Reference< XComponentContext >& rxContext ) :UnoControlModel_Base() - ,OPropertySetHelper( m_aBHelper ) ,maDisposeListeners( *this ) ,m_xContext( rxContext ) { @@ -119,8 +118,7 @@ UnoControlModel::UnoControlModel( const Reference< XComponentContext >& rxContex } UnoControlModel::UnoControlModel( const UnoControlModel& rModel ) - : UnoControlModel_Base() - , OPropertySetHelper( m_aBHelper ) + : UnoControlModel_Base(), OPropertySetHelper() , maData( rModel.maData ) , maDisposeListeners( *this ) , m_xContext( rModel.m_xContext ) @@ -416,7 +414,7 @@ css::uno::Any UnoControlModel::queryAggregation( const css::uno::Type & rType ) { Any aRet = UnoControlModel_Base::queryAggregation( rType ); if ( !aRet.hasValue() ) - aRet = ::cppu::OPropertySetHelper::queryInterface( rType ); + aRet = ::comphelper::OPropertySetHelper::queryInterface( rType ); return aRet; } @@ -424,7 +422,7 @@ css::uno::Any UnoControlModel::queryAggregation( const css::uno::Type & rType ) IMPLEMENT_FORWARD_REFCOUNT( UnoControlModel, UnoControlModel_Base ) // css::lang::XTypeProvider -IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::cppu::OPropertySetHelper ) +IMPLEMENT_FORWARD_XTYPEPROVIDER2( UnoControlModel, UnoControlModel_Base, ::comphelper::OPropertySetHelper ) uno::Reference< util::XCloneable > UnoControlModel::createClone() @@ -436,28 +434,26 @@ uno::Reference< util::XCloneable > UnoControlModel::createClone() // css::lang::XComponent void UnoControlModel::dispose( ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); css::lang::EventObject aEvt; aEvt.Source = static_cast<css::uno::XAggregation*>(static_cast<cppu::OWeakAggObject*>(this)); - maDisposeListeners.disposeAndClear( aEvt ); - - m_aBHelper.aLC.disposeAndClear( aEvt ); + maDisposeListeners.disposeAndClear( aGuard, aEvt ); // let the property set helper notify our property listeners - OPropertySetHelper::disposing(); + OPropertySetHelper::disposing(aGuard); } void UnoControlModel::addEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); maDisposeListeners.addInterface( rxListener ); } void UnoControlModel::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& rxListener ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); maDisposeListeners.removeInterface( rxListener ); } @@ -466,11 +462,15 @@ void UnoControlModel::removeEventListener( const css::uno::Reference< css::lang: // css::beans::XPropertyState css::beans::PropertyState UnoControlModel::getPropertyState( const OUString& PropertyName ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); + return getPropertyStateImpl(aGuard, PropertyName); +} +css::beans::PropertyState UnoControlModel::getPropertyStateImpl( std::unique_lock<std::mutex>& rGuard, const OUString& PropertyName ) +{ sal_uInt16 nPropId = GetPropertyId( PropertyName ); - css::uno::Any aValue = getPropertyValue( PropertyName ); + css::uno::Any aValue = getPropertyValueImpl( rGuard, PropertyName ); css::uno::Any aDefault = ImplGetDefaultValue( nPropId ); return CompareProperties( aValue, aDefault ) ? css::beans::PropertyState_DEFAULT_VALUE : css::beans::PropertyState_DIRECT_VALUE; @@ -478,14 +478,15 @@ css::beans::PropertyState UnoControlModel::getPropertyState( const OUString& Pro css::uno::Sequence< css::beans::PropertyState > UnoControlModel::getPropertyStates( const css::uno::Sequence< OUString >& PropertyNames ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); sal_Int32 nNames = PropertyNames.getLength(); css::uno::Sequence< css::beans::PropertyState > aStates( nNames ); std::transform(PropertyNames.begin(), PropertyNames.end(), aStates.getArray(), - [this](const OUString& rName) -> css::beans::PropertyState { return getPropertyState(rName); }); + [this, &aGuard](const OUString& rName) -> css::beans::PropertyState + { return getPropertyStateImpl(aGuard, rName); }); return aStates; } @@ -494,7 +495,7 @@ void UnoControlModel::setPropertyToDefault( const OUString& PropertyName ) { Any aDefaultValue; { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); aDefaultValue = ImplGetDefaultValue( GetPropertyId( PropertyName ) ); } setPropertyValue( PropertyName, aDefaultValue ); @@ -502,7 +503,7 @@ void UnoControlModel::setPropertyToDefault( const OUString& PropertyName ) css::uno::Any UnoControlModel::getPropertyDefault( const OUString& rPropertyName ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); return ImplGetDefaultValue( GetPropertyId( rPropertyName ) ); } @@ -517,7 +518,7 @@ OUString UnoControlModel::getServiceName( ) void UnoControlModel::write( const css::uno::Reference< css::io::XObjectOutputStream >& OutStream ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); css::uno::Reference< css::io::XMarkableStream > xMark( OutStream, css::uno::UNO_QUERY ); DBG_ASSERT( xMark.is(), "write: no css::io::XMarkableStream!" ); @@ -529,7 +530,7 @@ void UnoControlModel::write( const css::uno::Reference< css::io::XObjectOutputSt for (const auto& rData : maData) { if ( ( ( GetPropertyAttribs( rData.first ) & css::beans::PropertyAttribute::TRANSIENT ) == 0 ) - && ( getPropertyState( GetPropertyName( rData.first ) ) != css::beans::PropertyState_DEFAULT_VALUE ) ) + && ( getPropertyStateImpl( aGuard, GetPropertyName( rData.first ) ) != css::beans::PropertyState_DEFAULT_VALUE ) ) { aProps.insert( rData.first ); } @@ -747,7 +748,7 @@ void UnoControlModel::write( const css::uno::Reference< css::io::XObjectOutputSt void UnoControlModel::read( const css::uno::Reference< css::io::XObjectInputStream >& InStream ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); css::uno::Reference< css::io::XMarkableStream > xMark( InStream, css::uno::UNO_QUERY ); DBG_ASSERT( xMark.is(), "read: no css::io::XMarkableStream!" ); @@ -990,7 +991,7 @@ void UnoControlModel::read( const css::uno::Reference< css::io::XObjectInputStre try { - setPropertyValues( aProps, aValues ); + setPropertyValuesImpl( aGuard, aProps, aValues ); } catch ( const Exception& ) { @@ -1001,7 +1002,7 @@ void UnoControlModel::read( const css::uno::Reference< css::io::XObjectInputStre { css::uno::Any aValue; aValue <<= *pFD; - setPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ), aValue ); + setPropertyValueImpl( aGuard, GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ), aValue ); } } @@ -1024,10 +1025,8 @@ css::uno::Sequence< OUString > UnoControlModel::getSupportedServiceNames( ) return { "com.sun.star.awt.UnoControlModel" }; } -sal_Bool UnoControlModel::convertFastPropertyValue( Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue ) +bool UnoControlModel::convertFastPropertyValue( std::unique_lock<std::mutex>& rGuard, Any & rConvertedValue, Any & rOldValue, sal_Int32 nPropId, const Any& rValue ) { - ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() ); - bool bVoid = rValue.getValueType().getTypeClass() == css::uno::TypeClass_VOID; if ( bVoid ) { @@ -1140,11 +1139,11 @@ sal_Bool UnoControlModel::convertFastPropertyValue( Any & rConvertedValue, Any & } // the current value - getFastPropertyValue( rOldValue, nPropId ); + getFastPropertyValue( rGuard, rOldValue, nPropId ); return !CompareProperties( rConvertedValue, rOldValue ); } -void UnoControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nPropId, const css::uno::Any& rValue ) +void UnoControlModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& /*rGuard*/, sal_Int32 nPropId, const css::uno::Any& rValue ) { // Missing: the fake solo properties of the FontDescriptor @@ -1156,10 +1155,8 @@ void UnoControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nPropId, const maData[ nPropId ] = rValue; } -void UnoControlModel::getFastPropertyValue( css::uno::Any& rValue, sal_Int32 nPropId ) const +void UnoControlModel::getFastPropertyValue( std::unique_lock<std::mutex>& /*rGuard*/, css::uno::Any& rValue, sal_Int32 nPropId ) const { - ::osl::Guard< ::osl::Mutex > aGuard( const_cast<UnoControlModel*>(this)->GetMutex() ); - ImplPropertyTable::const_iterator it = maData.find( nPropId ); const css::uno::Any* pProp = it == maData.end() ? nullptr : &(it->second); @@ -1214,25 +1211,23 @@ void UnoControlModel::getFastPropertyValue( css::uno::Any& rValue, sal_Int32 nPr } // css::beans::XPropertySet -void UnoControlModel::setPropertyValue( const OUString& rPropertyName, const css::uno::Any& rValue ) +void UnoControlModel::setPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, const OUString& rPropertyName, const css::uno::Any& rValue ) { sal_Int32 nPropId = static_cast<sal_Int32>(GetPropertyId( rPropertyName )); DBG_ASSERT( nPropId, "Invalid ID in UnoControlModel::setPropertyValue" ); if( !nPropId ) throw css::beans::UnknownPropertyException(rPropertyName); - setFastPropertyValue( nPropId, rValue ); + setFastPropertyValueImpl( rGuard, nPropId, rValue ); } // css::beans::XFastPropertySet -void UnoControlModel::setFastPropertyValue( sal_Int32 nPropId, const css::uno::Any& rValue ) +void UnoControlModel::setFastPropertyValueImpl( std::unique_lock<std::mutex>& rGuard, sal_Int32 nPropId, const css::uno::Any& rValue ) { if ( ( nPropId >= BASEPROPERTY_FONTDESCRIPTORPART_START ) && ( nPropId <= BASEPROPERTY_FONTDESCRIPTORPART_END ) ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); - Any aOldSingleValue; - getFastPropertyValue( aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START ); + getFastPropertyValue( rGuard, aOldSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START ); css::uno::Any* pProp = &maData[ BASEPROPERTY_FONTDESCRIPTOR ]; FontDescriptor aOldFontDescriptor; @@ -1248,14 +1243,13 @@ void UnoControlModel::setFastPropertyValue( sal_Int32 nPropId, const css::uno::A // also, we need fire a propertyChange event for the single property, since with // the above line, only an event for the FontDescriptor property will be fired Any aNewSingleValue; - getFastPropertyValue( aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START ); + getFastPropertyValue( rGuard, aNewSingleValue, BASEPROPERTY_FONTDESCRIPTORPART_START ); - aGuard.clear(); - setFastPropertyValues( 1, &nDescriptorId, &aNewValue, 1 ); - fire( &nPropId, &aNewSingleValue, &aOldSingleValue, 1, false ); + setFastPropertyValues( rGuard, 1, &nDescriptorId, &aNewValue, 1 ); + fire( rGuard, &nPropId, &aNewSingleValue, &aOldSingleValue, 1, false ); } else - setFastPropertyValues( 1, &nPropId, &rValue, 1 ); + setFastPropertyValues( rGuard, 1, &nPropId, &rValue, 1 ); } // css::beans::XMultiPropertySet @@ -1267,8 +1261,12 @@ css::uno::Reference< css::beans::XPropertySetInfo > UnoControlModel::getProperty void UnoControlModel::setPropertyValues( const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); + setPropertyValuesImpl(aGuard, rPropertyNames, Values); +} +void UnoControlModel::setPropertyValuesImpl( std::unique_lock<std::mutex>& rGuard, const css::uno::Sequence< OUString >& rPropertyNames, const css::uno::Sequence< css::uno::Any >& Values ) +{ sal_Int32 nProps = rPropertyNames.getLength(); if (nProps != Values.getLength()) throw css::lang::IllegalArgumentException("lengths do not match", @@ -1310,16 +1308,8 @@ void UnoControlModel::setPropertyValues( const css::uno::Sequence< OUString >& r if ( nValidHandles ) { ImplNormalizePropertySequence( nProps, pHandles, pValues, &nValidHandles ); - aGuard.clear(); - // clear our guard before calling into setFastPropertyValues - this method - // will implicitly call property listeners, and this should not happen with - // our mutex locked - // #i23451# - setFastPropertyValues( nProps, pHandles, pValues, nValidHandles ); + setFastPropertyValues( rGuard, nProps, pHandles, pValues, nValidHandles ); } - else - aGuard.clear(); - // same as a few lines above // Don't merge FD property into array, as it is sorted if (pFD) @@ -1327,7 +1317,7 @@ void UnoControlModel::setPropertyValues( const css::uno::Sequence< OUString >& r css::uno::Any aValue; aValue <<= *pFD; sal_Int32 nHandle = BASEPROPERTY_FONTDESCRIPTOR; - setFastPropertyValues( 1, &nHandle, &aValue, 1 ); + setFastPropertyValues( rGuard, 1, &nHandle, &aValue, 1 ); } } diff --git a/toolkit/source/controls/unocontrols.cxx b/toolkit/source/controls/unocontrols.cxx index 84fe8ce50774..c8a3f8c839a3 100644 --- a/toolkit/source/controls/unocontrols.cxx +++ b/toolkit/source/controls/unocontrols.cxx @@ -589,9 +589,9 @@ uno::Any GraphicControlModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const return UnoControlModel::ImplGetDefaultValue( nPropId ); } -void SAL_CALL GraphicControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const css::uno::Any& rValue ) +void GraphicControlModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const css::uno::Any& rValue ) { - UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue ); // - ImageAlign and ImagePosition need to correspond to each other // - Graphic and ImageURL need to correspond to each other @@ -605,7 +605,7 @@ void SAL_CALL GraphicControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 n mbAdjustingGraphic = true; OUString sImageURL; OSL_VERIFY( rValue >>= sImageURL ); - setDependentFastPropertyValue( BASEPROPERTY_GRAPHIC, uno::Any( ImageHelper::getGraphicFromURL_nothrow( sImageURL ) ) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_GRAPHIC, uno::Any( ImageHelper::getGraphicFromURL_nothrow( sImageURL ) ) ); mbAdjustingGraphic = false; } break; @@ -614,7 +614,7 @@ void SAL_CALL GraphicControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 n if ( !mbAdjustingGraphic && ImplHasProperty( BASEPROPERTY_IMAGEURL ) ) { mbAdjustingGraphic = true; - setDependentFastPropertyValue( BASEPROPERTY_IMAGEURL, uno::Any( OUString() ) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_IMAGEURL, uno::Any( OUString() ) ); mbAdjustingGraphic = false; } break; @@ -625,7 +625,7 @@ void SAL_CALL GraphicControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 n mbAdjustingImagePosition = true; sal_Int16 nUNOValue = 0; OSL_VERIFY( rValue >>= nUNOValue ); - setDependentFastPropertyValue( BASEPROPERTY_IMAGEPOSITION, uno::Any( getExtendedImagePosition( nUNOValue ) ) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_IMAGEPOSITION, uno::Any( getExtendedImagePosition( nUNOValue ) ) ); mbAdjustingImagePosition = false; } break; @@ -635,7 +635,7 @@ void SAL_CALL GraphicControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 n mbAdjustingImagePosition = true; sal_Int16 nUNOValue = 0; OSL_VERIFY( rValue >>= nUNOValue ); - setDependentFastPropertyValue( BASEPROPERTY_IMAGEALIGN, uno::Any( getCompatibleImageAlign( translateImagePosition( nUNOValue ) ) ) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_IMAGEALIGN, uno::Any( getCompatibleImageAlign( translateImagePosition( nUNOValue ) ) ) ); mbAdjustingImagePosition = false; } break; @@ -658,7 +658,8 @@ UnoControlButtonModel::UnoControlButtonModel( const Reference< XComponentContext osl_atomic_increment( &m_refCount ); { - setFastPropertyValue_NoBroadcast( BASEPROPERTY_IMAGEPOSITION, ImplGetDefaultValue( BASEPROPERTY_IMAGEPOSITION ) ); + std::unique_lock aGuard(m_aMutex); + setFastPropertyValue_NoBroadcast( aGuard, BASEPROPERTY_IMAGEPOSITION, ImplGetDefaultValue( BASEPROPERTY_IMAGEPOSITION ) ); // this ensures that our ImagePosition is consistent with our ImageAlign property (since both // defaults are not per se consistent), since both are coupled in setFastPropertyValue_NoBroadcast } @@ -941,9 +942,9 @@ uno::Reference< beans::XPropertySetInfo > UnoControlImageControlModel::getProper return xInfo; } -void SAL_CALL UnoControlImageControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const css::uno::Any& _rValue ) +void UnoControlImageControlModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 _nHandle, const css::uno::Any& _rValue ) { - GraphicControlModel::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); + GraphicControlModel::setFastPropertyValue_NoBroadcast( rGuard, _nHandle, _rValue ); // ScaleImage is an older (and less powerful) version of ScaleMode, but keep both in sync as far as possible try @@ -956,7 +957,7 @@ void SAL_CALL UnoControlImageControlModel::setFastPropertyValue_NoBroadcast( sal mbAdjustingImageScaleMode = true; sal_Int16 nScaleMode( awt::ImageScaleMode::ANISOTROPIC ); OSL_VERIFY( _rValue >>= nScaleMode ); - setDependentFastPropertyValue( BASEPROPERTY_SCALEIMAGE, uno::Any( nScaleMode != awt::ImageScaleMode::NONE ) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_SCALEIMAGE, uno::Any( nScaleMode != awt::ImageScaleMode::NONE ) ); mbAdjustingImageScaleMode = false; } break; @@ -966,7 +967,7 @@ void SAL_CALL UnoControlImageControlModel::setFastPropertyValue_NoBroadcast( sal mbAdjustingImageScaleMode = true; bool bScale = true; OSL_VERIFY( _rValue >>= bScale ); - setDependentFastPropertyValue( BASEPROPERTY_IMAGE_SCALE_MODE, uno::Any( bScale ? awt::ImageScaleMode::ANISOTROPIC : awt::ImageScaleMode::NONE ) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_IMAGE_SCALE_MODE, uno::Any( bScale ? awt::ImageScaleMode::ANISOTROPIC : awt::ImageScaleMode::NONE ) ); mbAdjustingImageScaleMode = false; } break; @@ -2053,7 +2054,6 @@ private: UnoControlListBoxModel::UnoControlListBoxModel( const Reference< XComponentContext >& rxContext, ConstructorMode const i_mode ) :UnoControlListBoxModel_Base( rxContext ) ,m_xData( new UnoControlListBoxModel_Data( *this ) ) - ,m_aItemListListeners( GetMutex() ) { if ( i_mode == ConstructDefault ) { @@ -2064,7 +2064,6 @@ UnoControlListBoxModel::UnoControlListBoxModel( const Reference< XComponentConte UnoControlListBoxModel::UnoControlListBoxModel( const UnoControlListBoxModel& i_rSource ) :UnoControlListBoxModel_Base( i_rSource ) ,m_xData( new UnoControlListBoxModel_Data( *this ) ) - ,m_aItemListListeners( GetMutex() ) { m_xData->copyItems( *i_rSource.m_xData ); } @@ -2126,16 +2125,16 @@ namespace } -void SAL_CALL UnoControlListBoxModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) +void UnoControlListBoxModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const uno::Any& rValue ) { - UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue ); if ( nHandle != BASEPROPERTY_STRINGITEMLIST ) return; // reset selection uno::Sequence<sal_Int16> aSeq; - setDependentFastPropertyValue( BASEPROPERTY_SELECTEDITEMS, uno::Any(aSeq) ); + setDependentFastPropertyValue( rGuard, BASEPROPERTY_SELECTEDITEMS, uno::Any(aSeq) ); if ( m_xData->m_bSettingLegacyProperty ) return; @@ -2143,7 +2142,7 @@ void SAL_CALL UnoControlListBoxModel::setFastPropertyValue_NoBroadcast( sal_Int3 // synchronize the legacy StringItemList property with our list items Sequence< OUString > aStringItemList; Any aPropValue; - getFastPropertyValue( aPropValue, BASEPROPERTY_STRINGITEMLIST ); + getFastPropertyValue( rGuard, aPropValue, BASEPROPERTY_STRINGITEMLIST ); OSL_VERIFY( aPropValue >>= aStringItemList ); ::std::vector< ListItem > aItems( aStringItemList.getLength() ); @@ -2160,7 +2159,7 @@ void SAL_CALL UnoControlListBoxModel::setFastPropertyValue_NoBroadcast( sal_Int3 // items lang::EventObject aEvent; aEvent.Source = *this; - m_aItemListListeners.notifyEach( &XItemListListener::itemListChanged, aEvent ); + m_aItemListListeners.notifyEach( rGuard, &XItemListListener::itemListChanged, aEvent ); // TODO: OPropertySetHelper calls into this method with the mutex locked ... // which is wrong for the above notifications ... } @@ -2181,51 +2180,51 @@ void UnoControlListBoxModel::ImplNormalizePropertySequence( const sal_Int32 _nCo ::sal_Int32 SAL_CALL UnoControlListBoxModel::getItemCount() { - ::osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); return m_xData->getItemCount(); } void SAL_CALL UnoControlListBoxModel::insertItem( ::sal_Int32 i_nPosition, const OUString& i_rItemText, const OUString& i_rItemImageURL ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> ListItem& rItem( m_xData->insertItem( i_nPosition ) ); rItem.ItemText = i_rItemText; rItem.ItemImageURL = i_rItemImageURL; - impl_handleInsert( i_nPosition, i_rItemText, i_rItemImageURL, aGuard ); + impl_handleInsert( aGuard, i_nPosition, i_rItemText, i_rItemImageURL ); // <----- SYNCHRONIZED } void SAL_CALL UnoControlListBoxModel::insertItemText( ::sal_Int32 i_nPosition, const OUString& i_rItemText ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> ListItem& rItem( m_xData->insertItem( i_nPosition ) ); rItem.ItemText = i_rItemText; - impl_handleInsert( i_nPosition, i_rItemText, ::std::optional< OUString >(), aGuard ); + impl_handleInsert( aGuard, i_nPosition, i_rItemText, ::std::optional< OUString >() ); // <----- SYNCHRONIZED } void SAL_CALL UnoControlListBoxModel::insertItemImage( ::sal_Int32 i_nPosition, const OUString& i_rItemImageURL ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> ListItem& rItem( m_xData->insertItem( i_nPosition ) ); rItem.ItemImageURL = i_rItemImageURL; - impl_handleInsert( i_nPosition, ::std::optional< OUString >(), i_rItemImageURL, aGuard ); + impl_handleInsert( aGuard, i_nPosition, ::std::optional< OUString >(), i_rItemImageURL ); // <----- SYNCHRONIZED } void SAL_CALL UnoControlListBoxModel::removeItem( ::sal_Int32 i_nPosition ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> m_xData->removeItem( i_nPosition ); @@ -2236,7 +2235,7 @@ void SAL_CALL UnoControlListBoxModel::removeItem( ::sal_Int32 i_nPosition ) void SAL_CALL UnoControlListBoxModel::removeAllItems( ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> m_xData->removeAllItems(); @@ -2247,7 +2246,7 @@ void SAL_CALL UnoControlListBoxModel::removeAllItems( ) void SAL_CALL UnoControlListBoxModel::setItemText( ::sal_Int32 i_nPosition, const OUString& i_rItemText ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> ListItem& rItem( m_xData->getItem( i_nPosition ) ); rItem.ItemText = i_rItemText; @@ -2259,7 +2258,7 @@ void SAL_CALL UnoControlListBoxModel::setItemText( ::sal_Int32 i_nPosition, cons void SAL_CALL UnoControlListBoxModel::setItemImage( ::sal_Int32 i_nPosition, const OUString& i_rItemImageURL ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> ListItem& rItem( m_xData->getItem( i_nPosition ) ); rItem.ItemImageURL = i_rItemImageURL; @@ -2271,7 +2270,7 @@ void SAL_CALL UnoControlListBoxModel::setItemImage( ::sal_Int32 i_nPosition, con void SAL_CALL UnoControlListBoxModel::setItemTextAndImage( ::sal_Int32 i_nPosition, const OUString& i_rItemText, const OUString& i_rItemImageURL ) { - ::osl::ClearableMutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); // SYNCHRONIZED -----> ListItem& rItem( m_xData->getItem( i_nPosition ) ); rItem.ItemText = i_rItemText; @@ -2284,7 +2283,7 @@ void SAL_CALL UnoControlListBoxModel::setItemTextAndImage( ::sal_Int32 i_nPositi void SAL_CALL UnoControlListBoxModel::setItemData( ::sal_Int32 i_nPosition, const Any& i_rDataValue ) { - osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); ListItem& rItem( m_xData->getItem( i_nPosition ) ); rItem.ItemData = i_rDataValue; } @@ -2292,7 +2291,7 @@ void SAL_CALL UnoControlListBoxModel::setItemData( ::sal_Int32 i_nPosition, cons OUString SAL_CALL UnoControlListBoxModel::getItemText( ::sal_Int32 i_nPosition ) { - ::osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); const ListItem& rItem( m_xData->getItem( i_nPosition ) ); return rItem.ItemText; } @@ -2300,7 +2299,7 @@ OUString SAL_CALL UnoControlListBoxModel::getItemText( ::sal_Int32 i_nPosition ) OUString SAL_CALL UnoControlListBoxModel::getItemImage( ::sal_Int32 i_nPosition ) { - ::osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); const ListItem& rItem( m_xData->getItem( i_nPosition ) ); return rItem.ItemImageURL; } @@ -2308,7 +2307,7 @@ OUString SAL_CALL UnoControlListBoxModel::getItemImage( ::sal_Int32 i_nPosition beans::Pair< OUString, OUString > SAL_CALL UnoControlListBoxModel::getItemTextAndImage( ::sal_Int32 i_nPosition ) { - ::osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); const ListItem& rItem( m_xData->getItem( i_nPosition ) ); return beans::Pair< OUString, OUString >( rItem.ItemText, rItem.ItemImageURL ); } @@ -2316,7 +2315,7 @@ beans::Pair< OUString, OUString > SAL_CALL UnoControlListBoxModel::getItemTextAn Any SAL_CALL UnoControlListBoxModel::getItemData( ::sal_Int32 i_nPosition ) { - osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); const ListItem& rItem( m_xData->getItem( i_nPosition ) ); return rItem.ItemData; } @@ -2324,43 +2323,45 @@ Any SAL_CALL UnoControlListBoxModel::getItemData( ::sal_Int32 i_nPosition ) Sequence< beans::Pair< OUString, OUString > > SAL_CALL UnoControlListBoxModel::getAllItems( ) { - ::osl::MutexGuard aGuard( GetMutex() ); + std::unique_lock aGuard( m_aMutex ); return m_xData->getAllItems(); } void SAL_CALL UnoControlListBoxModel::addItemListListener( const uno::Reference< awt::XItemListListener >& i_Listener ) { + std::unique_lock aGuard( m_aMutex ); if ( i_Listener.is() ) - m_aItemListListeners.addInterface( i_Listener ); + m_aItemListListeners.addInterface( aGuard, i_Listener ); } void SAL_CALL UnoControlListBoxModel::removeItemListListener( const uno::Reference< awt::XItemListListener >& i_Listener ) { + std::unique_lock aGuard( m_aMutex ); if ( i_Listener.is() ) - m_aItemListListeners.removeInterface( i_Listener ); + m_aItemListListeners.removeInterface( aGuard, i_Listener ); } -void UnoControlListBoxModel::impl_getStringItemList( ::std::vector< OUString >& o_rStringItems ) const +void UnoControlListBoxModel::impl_getStringItemList( std::unique_lock<std::mutex>& rGuard, ::std::vector< OUString >& o_rStringItems ) const { Sequence< OUString > aStringItemList; Any aPropValue; - getFastPropertyValue( aPropValue, BASEPROPERTY_STRINGITEMLIST ); + getFastPropertyValue( rGuard, aPropValue, BASEPROPERTY_STRINGITEMLIST ); OSL_VERIFY( aPropValue >>= aStringItemList ); comphelper::sequenceToContainer(o_rStringItems, aStringItemList); } -void UnoControlListBoxModel::impl_setStringItemList_nolck( const ::std::vector< OUString >& i_rStringItems ) +void UnoControlListBoxModel::impl_setStringItemList( std::unique_lock<std::mutex>& rGuard, const ::std::vector< OUString >& i_rStringItems ) { Sequence< OUString > aStringItems( comphelper::containerToSequence(i_rStringItems) ); m_xData->m_bSettingLegacyProperty = true; try { - setFastPropertyValue( BASEPROPERTY_STRINGITEMLIST, uno::Any( aStringItems ) ); + setFastPropertyValueImpl( rGuard, BASEPROPERTY_STRINGITEMLIST, uno::Any( aStringItems ) ); } catch( const Exception& ) { @@ -2371,13 +2372,15 @@ void UnoControlListBoxModel::impl_setStringItemList_nolck( const ::std::vector< } -void UnoControlListBoxModel::impl_handleInsert( const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, - const ::std::optional< OUString >& i_rItemImageURL, ::osl::ClearableMutexGuard& i_rClearBeforeNotify ) +void UnoControlListBoxModel::impl_handleInsert( std::unique_lock<std::mutex>& rGuard, + const sal_Int32 i_nItemPosition, + const ::std::optional< OUString >& i_rItemText, + const ::std::optional< OUString >& i_rItemImageURL ) { // SYNCHRONIZED -----> // sync with legacy StringItemList property ::std::vector< OUString > aStringItems; - impl_getStringItemList( aStringItems ); + impl_getStringItemList( rGuard, aStringItems ); OSL_ENSURE( o3tl::make_unsigned( i_nItemPosition ) <= aStringItems.size(), "UnoControlListBoxModel::impl_handleInsert" ); if ( o3tl::make_unsigned( i_nItemPosition ) <= aStringItems.size() ) { @@ -2385,22 +2388,22 @@ void UnoControlListBoxModel::impl_handleInsert( const sal_Int32 i_nItemPosition, aStringItems.insert( aStringItems.begin() + i_nItemPosition, sItemText ); } - i_rClearBeforeNotify.clear(); - // <----- SYNCHRONIZED - impl_setStringItemList_nolck( aStringItems ); + impl_setStringItemList( rGuard, aStringItems ); // notify ItemListListeners - impl_notifyItemListEvent_nolck( i_nItemPosition, i_rItemText, i_rItemImageURL, &XItemListListener::listItemInserted ); + impl_notifyItemListEvent( rGuard, i_nItemPosition, i_rItemText, i_rItemImageURL, &XItemListListener::listItemInserted ); } -void UnoControlListBoxModel::impl_handleRemove( const sal_Int32 i_nItemPosition, ::osl::ClearableMutexGuard& i_rClearBeforeNotify ) +void UnoControlListBoxModel::impl_handleRemove( + const sal_Int32 i_nItemPosition, + std::unique_lock<std::mutex>& i_rClearBeforeNotify ) { // SYNCHRONIZED -----> const bool bAllItems = ( i_nItemPosition < 0 ); // sync with legacy StringItemList property ::std::vector< OUString > aStringItems; - impl_getStringItemList( aStringItems ); + impl_getStringItemList( i_rClearBeforeNotify, aStringItems ); if ( !bAllItems ) { OSL_ENSURE( o3tl::make_unsigned( i_nItemPosition ) < aStringItems.size(), "UnoControlListBoxModel::impl_handleRemove" ); @@ -2414,55 +2417,50 @@ void UnoControlListBoxModel::impl_handleRemove( const sal_Int32 i_nItemPosition, aStringItems.resize(0); } - i_rClearBeforeNotify.clear(); - // <----- SYNCHRONIZED - impl_setStringItemList_nolck( aStringItems ); + impl_setStringItemList( i_rClearBeforeNotify, aStringItems ); // notify ItemListListeners if ( bAllItems ) { EventObject aEvent( *this ); - m_aItemListListeners.notifyEach( &XItemListListener::allItemsRemoved, aEvent ); + m_aItemListListeners.notifyEach( i_rClearBeforeNotify, &XItemListListener::allItemsRemoved, aEvent ); } else { - impl_notifyItemListEvent_nolck( i_nItemPosition, ::std::optional< OUString >(), ::std::optional< OUString >(), + impl_notifyItemListEvent( i_rClearBeforeNotify, i_nItemPosition, ::std::optional< OUString >(), ::std::optional< OUString >(), &XItemListListener::listItemRemoved ); } } -void UnoControlListBoxModel::impl_handleModify( const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, - const ::std::optional< OUString >& i_rItemImageURL, ::osl::ClearableMutexGuard& i_rClearBeforeNotify ) +void UnoControlListBoxModel::impl_handleModify( + const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, + const ::std::optional< OUString >& i_rItemImageURL, + std::unique_lock<std::mutex>& i_rClearBeforeNotify ) { // SYNCHRONIZED -----> if ( !!i_rItemText ) { // sync with legacy StringItemList property ::std::vector< OUString > aStringItems; - impl_getStringItemList( aStringItems ); + impl_getStringItemList( i_rClearBeforeNotify, aStringItems ); OSL_ENSURE( o3tl::make_unsigned( i_nItemPosition ) < aStringItems.size(), "UnoControlListBoxModel::impl_handleModify" ); if ( o3tl::make_unsigned( i_nItemPosition ) < aStringItems.size() ) { aStringItems[ i_nItemPosition] = *i_rItemText; } - i_rClearBeforeNotify.clear(); - // <----- SYNCHRONIZED - impl_setStringItemList_nolck( aStringItems ); - } - else - { - i_rClearBeforeNotify.clear(); - // <----- SYNCHRONIZED + impl_setStringItemList( i_rClearBeforeNotify, aStringItems ); } // notify ItemListListeners - impl_notifyItemListEvent_nolck( i_nItemPosition, i_rItemText, i_rItemImageURL, &XItemListListener::listItemModified ); + impl_notifyItemListEvent( i_rClearBeforeNotify, i_nItemPosition, i_rItemText, i_rItemImageURL, &XItemListListener::listItemModified ); } -void UnoControlListBoxModel::impl_notifyItemListEvent_nolck( const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, +void UnoControlListBoxModel::impl_notifyItemListEvent( + std::unique_lock<std::mutex>& rGuard, + const sal_Int32 i_nItemPosition, const ::std::optional< OUString >& i_rItemText, const ::std::optional< OUString >& i_rItemImageURL, void ( SAL_CALL XItemListListener::*NotificationMethod )( const ItemListEvent& ) ) { @@ -2480,7 +2478,7 @@ void UnoControlListBoxModel::impl_notifyItemListEvent_nolck( const sal_Int32 i_n aEvent.ItemImageURL.Value = *i_rItemImageURL; } - m_aItemListListeners.notifyEach( NotificationMethod, aEvent ); + m_aItemListListeners.notifyEach( rGuard, NotificationMethod, aEvent ); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * @@ -2940,9 +2938,9 @@ OUString UnoControlComboBoxModel::getServiceName() return "stardiv.vcl.controlmodel.ComboBox"; } -void SAL_CALL UnoControlComboBoxModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) +void UnoControlComboBoxModel::setFastPropertyValue_NoBroadcast( std::unique_lock<std::mutex>& rGuard, sal_Int32 nHandle, const uno::Any& rValue ) { - UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard, nHandle, rValue ); if (nHandle != BASEPROPERTY_STRINGITEMLIST || m_xData->m_bSettingLegacyProperty) return; @@ -2950,7 +2948,7 @@ void SAL_CALL UnoControlComboBoxModel::setFastPropertyValue_NoBroadcast( sal_Int // synchronize the legacy StringItemList property with our list items Sequence< OUString > aStringItemList; Any aPropValue; - getFastPropertyValue( aPropValue, BASEPROPERTY_STRINGITEMLIST ); + getFastPropertyValue( rGuard, aPropValue, BASEPROPERTY_STRINGITEMLIST ); OSL_VERIFY( aPropValue >>= aStringItemList ); ::std::vector< ListItem > aItems( aStringItemList.getLength() ); @@ -2967,9 +2965,7 @@ void SAL_CALL UnoControlComboBoxModel::setFastPropertyValue_NoBroadcast( sal_Int // items lang::EventObject aEvent; aEvent.Source = *this; - m_aItemListListeners.notifyEach( &XItemListListener::itemListChanged, aEvent ); - // TODO: OPropertySetHelper calls into this method with the mutex locked ... - // which is wrong for the above notifications ... + m_aItemListListeners.notifyEach( rGuard, &XItemListListener::itemListChanged, aEvent ); } uno::Any UnoControlComboBoxModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const |