LibreOffice Module comphelper (master) 1
MasterPropertySet.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
26
27
28#include <memory>
29#include <vector>
30#include <optional>
31
32namespace {
33
34class AutoOGuardArray
35{
36 std::vector<std::optional< osl::Guard< comphelper::SolarMutex > >> maGuardArray;
37
38public:
39 explicit AutoOGuardArray( sal_Int32 nNumElements );
40
41 std::optional< osl::Guard< comphelper::SolarMutex > > & operator[] ( sal_Int32 i ) { return maGuardArray[i]; }
42};
43
44}
45
46AutoOGuardArray::AutoOGuardArray( sal_Int32 nNumElements ) : maGuardArray(nNumElements)
47{
48}
49
50
51using namespace ::comphelper;
52using namespace ::com::sun::star;
53using namespace ::com::sun::star::uno;
54using namespace ::com::sun::star::lang;
55using namespace ::com::sun::star::beans;
56
57
58SlaveData::SlaveData ( ChainablePropertySet *pSlave)
59: mxSlave ( pSlave )
60, mbInit ( false )
61{
62}
63
65 noexcept
66: mpMutex ( pMutex )
67, mnLastId ( 0 )
68, mxInfo ( pInfo )
69{
70}
71
73 noexcept
74{
75 for( const auto& rSlave : maSlaveMap )
76 delete rSlave.second;
77}
78
79// XPropertySet
80Reference< XPropertySetInfo > SAL_CALL MasterPropertySet::getPropertySetInfo( )
81{
82 return mxInfo;
83}
84
86 noexcept
87{
88 maSlaveMap [ ++mnLastId ] = new SlaveData ( pNewSet );
89 mxInfo->add ( pNewSet->mxInfo->maMap, mnLastId );
90}
91
92void SAL_CALL MasterPropertySet::setPropertyValue( const OUString& rPropertyName, const Any& rValue )
93{
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 );
98
99 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
100
101 if( aIter == mxInfo->maMap.end())
102 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
103
104 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
105 {
107 _setSingleValue( *((*aIter).second->mpInfo), rValue );
109 }
110 else
111 {
112 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
113
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 );
118
119 pSlave->_preSetValues();
120 pSlave->_setSingleValue( *((*aIter).second->mpInfo), rValue );
121 pSlave->_postSetValues();
122 }
123}
124
125Any SAL_CALL MasterPropertySet::getPropertyValue( const OUString& rPropertyName )
126{
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 );
131
132 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
133
134 if( aIter == mxInfo->maMap.end())
135 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
136
137 Any aAny;
138 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
139 {
141 _getSingleValue( *((*aIter).second->mpInfo), aAny );
143 }
144 else
145 {
146 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
147
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 );
152
153 pSlave->_preGetValues();
154 pSlave->_getSingleValue( *((*aIter).second->mpInfo), aAny );
155 pSlave->_postGetValues();
156 }
157 return aAny;
158}
159
160void SAL_CALL MasterPropertySet::addPropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
161{
162 // todo
163}
164
165void SAL_CALL MasterPropertySet::removePropertyChangeListener( const OUString&, const Reference< XPropertyChangeListener >& )
166{
167 // todo
168}
169
170void SAL_CALL MasterPropertySet::addVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
171{
172 // todo
173}
174
175void SAL_CALL MasterPropertySet::removeVetoableChangeListener( const OUString&, const Reference< XVetoableChangeListener >& )
176{
177 // todo
178}
179
180// XMultiPropertySet
181void SAL_CALL MasterPropertySet::setPropertyValues( const Sequence< OUString >& aPropertyNames, const Sequence< Any >& aValues )
182{
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 );
187
188 const sal_Int32 nCount = aPropertyNames.getLength();
189
190 if( nCount != aValues.getLength() )
191 throw IllegalArgumentException();
192
193 if( !nCount )
194 return;
195
197
198 const Any * pAny = aValues.getConstArray();
199 const OUString * pString = aPropertyNames.getConstArray();
200 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
201
207 AutoOGuardArray aOGuardArray( nCount );
208
209 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
210 {
211 aIter = mxInfo->maMap.find ( *pString );
212 if ( aIter == aEnd )
213 throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) );
214
215 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
216 _setSingleValue( *((*aIter).second->mpInfo), *pAny );
217 else
218 {
219 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
220 if (!pSlave->IsInit())
221 {
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 );
225
226 pSlave->mxSlave->_preSetValues();
227 pSlave->SetInit ( true );
228 }
229 pSlave->mxSlave->_setSingleValue( *((*aIter).second->mpInfo), *pAny );
230 }
231 }
232
234 for( const auto& rSlave : maSlaveMap )
235 {
236 if( rSlave.second->IsInit() )
237 {
238 rSlave.second->mxSlave->_postSetValues();
239 rSlave.second->SetInit( false );
240 }
241 }
242}
243
244Sequence< Any > SAL_CALL MasterPropertySet::getPropertyValues( const Sequence< OUString >& aPropertyNames )
245{
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 );
250
251 const sal_Int32 nCount = aPropertyNames.getLength();
252
253 Sequence < Any > aValues ( nCount );
254
255 if( nCount )
256 {
258
259 Any * pAny = aValues.getArray();
260 const OUString * pString = aPropertyNames.getConstArray();
261 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
262
268 AutoOGuardArray aOGuardArray( nCount );
269
270 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pAny )
271 {
272 aIter = mxInfo->maMap.find ( *pString );
273 if ( aIter == aEnd )
274 throw RuntimeException( *pString, static_cast< XPropertySet* >( this ) );
275
276 if ( (*aIter).second->mnMapId == 0 ) // 0 means it's one of ours !
277 _getSingleValue( *((*aIter).second->mpInfo), *pAny );
278 else
279 {
280 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
281 if (!pSlave->IsInit())
282 {
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 );
286
287 pSlave->mxSlave->_preGetValues();
288 pSlave->SetInit ( true );
289 }
290 pSlave->mxSlave->_getSingleValue( *((*aIter).second->mpInfo), *pAny );
291 }
292 }
293
295 for( const auto& rSlave : maSlaveMap )
296 {
297 if( rSlave.second->IsInit() )
298 {
299 rSlave.second->mxSlave->_postSetValues();
300 rSlave.second->SetInit( false );
301 }
302 }
303 }
304 return aValues;
305}
306
307void SAL_CALL MasterPropertySet::addPropertiesChangeListener( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
308{
309 // todo
310}
311
312void SAL_CALL MasterPropertySet::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& )
313{
314 // todo
315}
316
317void SAL_CALL MasterPropertySet::firePropertiesChangeEvent( const Sequence< OUString >&, const Reference< XPropertiesChangeListener >& )
318{
319 // todo
320}
321
322// XPropertyState
323PropertyState SAL_CALL MasterPropertySet::getPropertyState( const OUString& PropertyName )
324{
325 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find( PropertyName );
326 if( aIter == mxInfo->maMap.end())
327 throw UnknownPropertyException( PropertyName, static_cast< XPropertySet* >( this ) );
328
329 // 0 means it's one of ours !
330 if ( (*aIter).second->mnMapId != 0 )
331 {
332 ChainablePropertySet * pSlave = maSlaveMap [ (*aIter).second->mnMapId ]->mxSlave.get();
333
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 );
338 }
339
340 return PropertyState_AMBIGUOUS_VALUE;
341}
342
343Sequence< PropertyState > SAL_CALL MasterPropertySet::getPropertyStates( const Sequence< OUString >& rPropertyNames )
344{
345 const sal_Int32 nCount = rPropertyNames.getLength();
346
347 Sequence< PropertyState > aStates( nCount );
348 if( nCount )
349 {
350 PropertyState * pState = aStates.getArray();
351 const OUString * pString = rPropertyNames.getConstArray();
352 PropertyDataHash::const_iterator aEnd = mxInfo->maMap.end(), aIter;
353
354 for ( sal_Int32 i = 0; i < nCount; ++i, ++pString, ++pState )
355 {
356 aIter = mxInfo->maMap.find ( *pString );
357 if ( aIter == aEnd )
358 throw UnknownPropertyException( *pString, static_cast< XPropertySet* >( this ) );
359
360 // 0 means it's one of ours !
361 if ( (*aIter).second->mnMapId != 0 )
362 {
363 SlaveData * pSlave = maSlaveMap [ (*aIter).second->mnMapId ];
364 if (!pSlave->IsInit())
365 {
366 pSlave->SetInit ( true );
367 }
368 }
369 }
370 for( const auto& rSlave : maSlaveMap )
371 {
372 if( rSlave.second->IsInit() )
373 {
374 rSlave.second->SetInit( false );
375 }
376 }
377 }
378 return aStates;
379}
380
381void SAL_CALL MasterPropertySet::setPropertyToDefault( const OUString& rPropertyName )
382{
383 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
384
385 if( aIter == mxInfo->maMap.end())
386 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
387}
388
389Any SAL_CALL MasterPropertySet::getPropertyDefault( const OUString& rPropertyName )
390{
391 PropertyDataHash::const_iterator aIter = mxInfo->maMap.find ( rPropertyName );
392
393 if( aIter == mxInfo->maMap.end())
394 throw UnknownPropertyException( rPropertyName, static_cast< XPropertySet* >( this ) );
395 return Any();
396}
397
398/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void _getSingleValue(const comphelper::PropertyInfo &rInfo, css::uno::Any &rValue)=0
virtual void _setSingleValue(const comphelper::PropertyInfo &rInfo, const css::uno::Any &rValue)=0
virtual void SAL_CALL firePropertiesChangeEvent(const css::uno::Sequence< OUString > &aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &xListener) override
virtual void SAL_CALL removeVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
virtual void SAL_CALL removePropertiesChangeListener(const css::uno::Reference< css::beans::XPropertiesChangeListener > &xListener) override
virtual void _preGetValues()=0
MasterPropertySet(comphelper::MasterPropertySetInfo *pInfo, SolarMutex *pMutex) noexcept
virtual void _setSingleValue(const comphelper::PropertyInfo &rInfo, const css::uno::Any &rValue)=0
virtual void SAL_CALL setPropertyValue(const OUString &aPropertyName, const css::uno::Any &aValue) override
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &PropertyName) override
virtual void _getSingleValue(const comphelper::PropertyInfo &rInfo, css::uno::Any &rValue)=0
virtual ~MasterPropertySet() noexcept
void registerSlave(ChainablePropertySet *pNewSet) noexcept
virtual css::beans::PropertyState SAL_CALL getPropertyState(const OUString &PropertyName) override
virtual void SAL_CALL addPropertiesChangeListener(const css::uno::Sequence< OUString > &aPropertyNames, const css::uno::Reference< css::beans::XPropertiesChangeListener > &xListener) override
virtual void SAL_CALL setPropertyToDefault(const OUString &PropertyName) override
virtual void SAL_CALL removePropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) override
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
virtual void _postGetValues()=0
virtual void _postSetValues()=0
virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< OUString > &aPropertyNames, const css::uno::Sequence< css::uno::Any > &aValues) override
virtual css::uno::Any SAL_CALL getPropertyDefault(const OUString &aPropertyName) override
virtual void SAL_CALL addPropertyChangeListener(const OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
virtual css::uno::Sequence< css::beans::PropertyState > SAL_CALL getPropertyStates(const css::uno::Sequence< OUString > &aPropertyName) override
rtl::Reference< MasterPropertySetInfo > mxInfo
virtual void _preSetValues()=0
virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPropertyValues(const css::uno::Sequence< OUString > &aPropertyNames) override
virtual void SAL_CALL addVetoableChangeListener(const OUString &PropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) override
std::map< sal_uInt8, comphelper::SlaveData * > maSlaveMap
SolarMutex, needed for VCL's Application::GetSolarMutex().
Definition: solarmutex.hxx:46
int nCount
class SAL_NO_VTABLE XPropertySet
int i
rtl::Reference< ChainablePropertySet > mxSlave
void SetInit(bool bInit)