android: Update app-specific/MIME type icons
[LibreOffice.git] / comphelper / source / property / MasterPropertySet.cxx
blob922a4c1c69b47d6d8f6af5f014ecc9fb390f41d3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <comphelper/MasterPropertySet.hxx>
22 #include <comphelper/MasterPropertySetInfo.hxx>
23 #include <comphelper/ChainablePropertySet.hxx>
24 #include <comphelper/ChainablePropertySetInfo.hxx>
25 #include <comphelper/solarmutex.hxx>
28 #include <memory>
29 #include <vector>
30 #include <optional>
32 namespace {
34 class AutoOGuardArray
36 std::vector<std::optional< osl::Guard< comphelper::SolarMutex > >> maGuardArray;
38 public:
39 explicit AutoOGuardArray( sal_Int32 nNumElements );
41 std::optional< osl::Guard< comphelper::SolarMutex > > & operator[] ( sal_Int32 i ) { return maGuardArray[i]; }
46 AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements ) : maGuardArray(nNumElements)
51 using namespace ::comphelper;
52 using namespace ::com::sun::star;
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::lang;
55 using namespace ::com::sun::star::beans;
58 SlaveData::SlaveData ( ChainablePropertySet *pSlave)
59 : mxSlave ( pSlave )
60 , mbInit ( false )
64 MasterPropertySet::MasterPropertySet( comphelper::MasterPropertySetInfo* pInfo, comphelper::SolarMutex* pMutex )
65 noexcept
66 : mpMutex ( pMutex )
67 , mnLastId ( 0 )
68 , mxInfo ( pInfo )
72 MasterPropertySet::~MasterPropertySet()
73 noexcept
75 for( const auto& rSlave : maSlaveMap )
76 delete rSlave.second;
79 // XPropertySet
80 Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( )
82 return mxInfo;
85 void MasterPropertySet::registerSlave ( ChainablePropertySet *pNewSet )
86 noexcept
88 maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet );
89 mxInfo->add ( pNewSet->mxInfo->maMap, mnLastId );
92 void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
94 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
95 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
96 if (mpMutex)
97 xMutexGuard.emplace( mpMutex );
99 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
101 if( aIter == mxInfo->maMap.end())
102 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
104 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
106 _preSetValues();
107 _setSingleValue( *((*aIter).second->mpInfo), rValue );
108 _postSetValues();
110 else
112 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
114 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
115 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard2;
116 if (pSlave->mpMutex)
117 xMutexGuard2.emplace( pSlave->mpMutex );
119 pSlave->_preSetValues();
120 pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue );
121 pSlave->_postSetValues();
125 Any SAL_CALL MasterPropertySet::getPropertyValue( const OUString& rPropertyName )
127 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
128 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
129 if (mpMutex)
130 xMutexGuard.emplace( mpMutex );
132 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
134 if( aIter == mxInfo->maMap.end())
135 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
137 Any aAny;
138 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
140 _preGetValues();
141 _getSingleValue( *((*aIter).second->mpInfo), aAny );
142 _postGetValues();
144 else
146 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
148 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
149 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard2;
150 if (pSlave->mpMutex)
151 xMutexGuard2.emplace( pSlave->mpMutex );
153 pSlave->_preGetValues();
154 pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny );
155 pSlave->_postGetValues();
157 return aAny;
160 void SAL_CALL MasterPropertySet::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
162 // todo
165 void SAL_CALL MasterPropertySet::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
167 // todo
170 void SAL_CALL MasterPropertySet::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
172 // todo
175 void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
177 // todo
180 // XMultiPropertySet
181 void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues )
183 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
184 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
185 if (mpMutex)
186 xMutexGuard.emplace( mpMutex );
188 const sal_Int32 nCount = aPropertyNames.getLength();
190 if( nCount != aValues.getLength() )
191 throw IllegalArgumentException();
193 if( !nCount )
194 return;
196 _preSetValues();
198 const Any * pAny = aValues.getConstArray();
199 const OUString * pString = aPropertyNames.getConstArray();
200 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
202 //!! have a unique_ptr to an array of OGuards in order to have the
203 //!! allocated memory properly freed (exception safe!).
204 //!! Since the array itself has unique_ptrs as members we have to use a
205 //!! helper class 'AutoOGuardArray' in order to have
206 //!! the acquired locks properly released.
207 AutoOGuardArray aOGuardArray( nCount );
209 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
211 aIter = mxInfo->maMap.find ( *pString );
212 if ( aIter == aEnd )
213 throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) );
215 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
216 _setSingleValue( *((*aIter).second->mpInfo), *pAny );
217 else
219 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
220 if (!pSlave->IsInit())
222 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
223 if (pSlave->mxSlave->mpMutex)
224 aOGuardArray[i].emplace( pSlave->mxSlave->mpMutex );
226 pSlave->mxSlave->_preSetValues();
227 pSlave->SetInit ( true );
229 pSlave->mxSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny );
233 _postSetValues();
234 for( const auto& rSlave : maSlaveMap )
236 if( rSlave.second->IsInit() )
238 rSlave.second->mxSlave->_postSetValues();
239 rSlave.second->SetInit( false );
244 Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< OUString >& aPropertyNames )
246 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
247 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
248 if (mpMutex)
249 xMutexGuard.emplace( mpMutex );
251 const sal_Int32 nCount = aPropertyNames.getLength();
253 Sequence < Any > aValues ( nCount );
255 if( nCount )
257 _preGetValues();
259 Any * pAny = aValues.getArray();
260 const OUString * pString = aPropertyNames.getConstArray();
261 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
263 //!! have a unique_ptr to an array of OGuards in order to have the
264 //!! allocated memory properly freed (exception safe!).
265 //!! Since the array itself has unique_ptrs as members we have to use a
266 //!! helper class 'AutoOGuardArray' in order to have
267 //!! the acquired locks properly released.
268 AutoOGuardArray aOGuardArray( nCount );
270 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
272 aIter = mxInfo->maMap.find ( *pString );
273 if ( aIter == aEnd )
274 throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) );
276 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
277 _getSingleValue( *((*aIter).second->mpInfo), *pAny );
278 else
280 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
281 if (!pSlave->IsInit())
283 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
284 if (pSlave->mxSlave->mpMutex)
285 aOGuardArray[i].emplace( pSlave->mxSlave->mpMutex );
287 pSlave->mxSlave->_preGetValues();
288 pSlave->SetInit ( true );
290 pSlave->mxSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny );
294 _postSetValues();
295 for( const auto& rSlave : maSlaveMap )
297 if( rSlave.second->IsInit() )
299 rSlave.second->mxSlave->_postSetValues();
300 rSlave.second->SetInit( false );
304 return aValues;
307 void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
309 // todo
312 void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& )
314 // todo
317 void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
319 // todo
322 // XPropertyState
323 PropertyState SAL_CALL MasterPropertySet::getPropertyState( const OUString& PropertyName )
325 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find( PropertyName );
326 if( aIter == mxInfo->maMap.end())
327 throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) );
329 // 0 means it's one of ours !
330 if ( (*aIter).second->mnMapId != 0 )
332 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
334 // acquire mutex in c-tor and releases it in the d-tor (exception safe!).
335 std::optional< osl::Guard< comphelper::SolarMutex > > xMutexGuard;
336 if (pSlave->mpMutex)
337 xMutexGuard.emplace( pSlave->mpMutex );
340 return PropertyState_AMBIGUOUS_VALUE;
343 Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< OUString >& rPropertyNames )
345 const sal_Int32 nCount = rPropertyNames.getLength();
347 Sequence< PropertyState > aStates( nCount );
348 if( nCount )
350 PropertyState * pState = aStates.getArray();
351 const OUString * pString = rPropertyNames.getConstArray();
352 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
354 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState )
356 aIter = mxInfo->maMap.find ( *pString );
357 if ( aIter == aEnd )
358 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
360 // 0 means it's one of ours !
361 if ( (*aIter).second->mnMapId != 0 )
363 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
364 if (!pSlave->IsInit())
366 pSlave->SetInit ( true );
370 for( const auto& rSlave : maSlaveMap )
372 if( rSlave.second->IsInit() )
374 rSlave.second->SetInit( false );
378 return aStates;
381 void SAL_CALL MasterPropertySet::setPropertyToDefault( const OUString& rPropertyName )
383 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
385 if( aIter == mxInfo->maMap.end())
386 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
389 Any SAL_CALL MasterPropertySet::getPropertyDefault( const OUString& rPropertyName )
391 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
393 if( aIter == mxInfo->maMap.end())
394 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
395 return Any();
398 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */