/* -*- 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 .
*/
/** * 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;
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;
pR = static_cast<Property *>(bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), sizeof( Property ),
compare_OUString_Property_Impl )); return pR != nullptr;
}
/** * You must call disposing before.
*/
OPropertySetHelper::~OPropertySetHelper()
{ delete m_pReserved;
}
OPropertySetHelper2::~OPropertySetHelper2()
{
}
// 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 ) );
}
Any OPropertySetHelper2::queryInterface( const css::uno::Type & rType )
{
Any cnd(cppu::queryInterface(rType, static_cast< XPropertySetOption * >(this))); if ( cnd.hasValue() ) return cnd; return OPropertySetHelper::queryInterface(rType);
}
/** * 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()
{ // 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( aEvt );
aVetoableLC.disposeAndClear( aEvt );
}
// XPropertySet void OPropertySetHelper::setPropertyValue( 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
setFastPropertyValue( nHandle, rValue );
}
// XPropertySet
Any OPropertySetHelper::getPropertyValue( const OUString& rPropertyName )
{ // get the map table
IPropertyArrayHelper & rPH = getInfoHelper(); // map the name to the handle
sal_Int32 nHandle = rPH.getHandleByName( rPropertyName ); if (nHandle == -1) throw UnknownPropertyException(rPropertyName); // call the method of the XFastPropertySet interface return getFastPropertyValue( nHandle );
}
// 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( nHandle, rxListener );
} else // add the change listener to the helper container
rBHelper.aLC.addInterface(
getPropertyTypeIdentifier( ),
rxListener
);
}
// XPropertySet void OPropertySetHelper::removePropertyChangeListener( const OUString& rPropertyName, const Reference < XPropertyChangeListener >& rxListener )
{
MutexGuard aGuard( rBHelper.rMutex );
OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); // all listeners are automatically released in a dispose call if( rBHelper.bInDispose || rBHelper.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( nHandle, rxListener );
} else { // remove the change listener to the helper container
rBHelper.aLC.removeInterface(
getPropertyTypeIdentifier( ),
rxListener
);
}
}
// 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( nHandle, rxListener );
} else // add the vetoable listener to the helper container
rBHelper.aLC.addInterface(
getVetoableTypeIdentifier( ),
rxListener
);
}
// XPropertySet void OPropertySetHelper::removeVetoableChangeListener( const OUString& rPropertyName, const Reference < XVetoableChangeListener > & rxListener )
{
MutexGuard aGuard( rBHelper.rMutex );
OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" ); // all listeners are automatically released in a dispose call if( rBHelper.bInDispose || rBHelper.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( nHandle, rxListener );
} else // add the vetoable listener to the helper container
rBHelper.aLC.removeInterface(
getVetoableTypeIdentifier( ),
rxListener
);
}
void OPropertySetHelper::setDependentFastPropertyValue( sal_Int32 i_handle, const css::uno::Any& i_value )
{ //OSL_PRECOND( rBHelper.rMutex.isAcquired(), "OPropertySetHelper::setDependentFastPropertyValue: to be called with a locked mutex only!" ); // there is no such thing as Mutex.isAcquired, sadly ...
// 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( 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( 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_pReserved->m_handles.push_back( i_handle );
m_pReserved->m_newValues.push_back( aConverted ); // TODO: setFastPropertyValue notifies the unconverted value here ...?
m_pReserved->m_oldValues.push_back( aOld );
}
// XFastPropertySet void OPropertySetHelper::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
{
OSL_ENSURE( !rBHelper.bInDispose, "do not setFastPropertyValue in the dispose call" );
OSL_ENSURE( !rBHelper.bDisposed, "object is disposed" );
// Will the property change? bool bChanged;
{
MutexGuard aGuard( rBHelper.rMutex );
bChanged = convertFastPropertyValue( aConvertedVal, aOldVal, nHandle, rValue ); // release guard to fire events
} 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( &nHandle, &rValue, &aOldVal, 1, true );
}
{
MutexGuard aGuard( rBHelper.rMutex ); try
{ // set the property to the new value
setFastPropertyValue_NoBroadcast( 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;
}
// release guard to fire events
} // file a change event, if the value changed
impl_fireAll( &nHandle, &rValue, &aOldVal, 1 );
}
// XFastPropertySet
Any OPropertySetHelper::getFastPropertyValue( sal_Int32 nHandle )
{
assert(nHandle != -1 && "passing -1 here indicates that the caller knows this is not a valid handle");
IPropertyArrayHelper & rInfo = getInfoHelper(); if( !rInfo.fillPropertyMembersByHandle( nullptr, nullptr, nHandle ) ) // unknown property throw UnknownPropertyException(OUString::number(nHandle));
void OPropertySetHelper::fire
(
sal_Int32 * pnHandles, const Any * pNewValues, const Any * pOldValues,
sal_Int32 nHandles, // This is the Count of the array
sal_Bool bVetoable
)
{ if (! m_pReserved->m_bFireEvents) return;
if (m_pReserved->m_pFireEvents) {
m_pReserved->m_pFireEvents->fireEvents(
pnHandles, nHandles, bVetoable,
m_pReserved->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] );
{ // must lock the mutex outside the loop. So all values are consistent.
MutexGuard aGuard( rBHelper.rMutex ); 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( pConvertedValues[ n ], pOldValues[n],
pHandles[i], pValues[i] ) )
{ // only increment if the property really change
pHandles[n] = pHandles[i];
n++;
}
}
} // release guard to fire events
}
// fire vetoable events
fire( pHandles, pConvertedValues.get(), pOldValues.get(), n, true );
{ // must lock the mutex outside the loop.
MutexGuard aGuard( rBHelper.rMutex ); // Loop over all changed properties for( i = 0; i < n; i++ )
{ // Will the property change?
setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
} // release guard to fire events
}
// fire change events
impl_fireAll( 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(u"lengths do not match"_ustr, 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 )
setFastPropertyValues( nSeqLen, pHandles.get(), rValues.getConstArray(), nHitCount );
}
// get the map table
IPropertyArrayHelper & rPH = getInfoHelper(); // fill the handle array
rPH.fillHandles( pHandles.get(), rPropertyNames );
Any * pValues = aValues.getArray();
MutexGuard aGuard( rBHelper.rMutex ); // fill the sequence with the values for( sal_Int32 i = 0; i < nSeqLen; i++ )
getFastPropertyValue( pValues[i], pHandles[i] );
for( i = 1; i < nElements; i++ )
{ if (aInfos[i - 1].Name > aInfos[i].Name)
{ if (bSorted) {
OSL_FAIL( "Property array is not sorted" );
} // not sorted
qsort( aInfos.getArray(), nElements, sizeof( Property ),
compare_Property_Impl ); break;
}
} for( i = 0; i < nElements; i++ ) if (aInfos[i].Handle != i) return; // The handle is the index
bRightOrdered = true;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.