comphelper/Library_comphelper.mk | 1 comphelper/source/property/propshlp.cxx | 880 ++++++++++++++++++ include/comphelper/compbase.hxx | 6 include/comphelper/propshlp.hxx | 348 +++++++ include/comphelper/unoimplbase.hxx | 34 include/toolkit/controls/unocontrolmodel.hxx | 37 include/toolkit/controls/unocontrols.hxx | 65 - include/toolkit/helper/listenermultiplexer.hxx | 5 toolkit/inc/controls/animatedimages.hxx | 7 toolkit/inc/controls/controlmodelcontainerbase.hxx | 8 toolkit/inc/controls/dialogcontrol.hxx | 24 toolkit/inc/controls/formattedcontrol.hxx | 14 toolkit/inc/controls/roadmapcontrol.hxx | 2 toolkit/inc/controls/tabpagecontainer.hxx | 2 toolkit/inc/controls/tabpagemodel.hxx | 2 toolkit/inc/controls/tkscrollbar.hxx | 2 toolkit/inc/controls/unocontrolcontainermodel.hxx | 2 toolkit/source/controls/animatedimages.cxx | 46 toolkit/source/controls/controlmodelcontainerbase.cxx | 18 toolkit/source/controls/dialogcontrol.cxx | 17 toolkit/source/controls/formattedcontrol.cxx | 39 toolkit/source/controls/grid/gridcontrol.cxx | 11 toolkit/source/controls/grid/gridcontrol.hxx | 4 toolkit/source/controls/spinningprogress.cxx | 6 toolkit/source/controls/tabpagecontainer.cxx | 6 toolkit/source/controls/tkspinbutton.cxx | 3 toolkit/source/controls/tree/treecontrol.hxx | 6 toolkit/source/controls/unocontrolmodel.cxx | 96 - toolkit/source/controls/unocontrols.cxx | 148 +-- 29 files changed, 1547 insertions(+), 292 deletions(-)
New commits: commit 30784e55e484de2790c4b264a50a65acf450c000 Author: Noel Grandin <[email protected]> AuthorDate: Wed Mar 8 13:15:39 2023 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Mon Mar 13 06:49:21 2023 +0000 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 <[email protected]> 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() ) ... etc. - the rest is truncated
