/src/libreoffice/toolkit/source/controls/geometrycontrolmodel.cxx
Line | Count | Source |
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 | | #include <controls/geometrycontrolmodel.hxx> |
21 | | #include <com/sun/star/beans/PropertyAttribute.hpp> |
22 | | #include <com/sun/star/resource/XStringResourceResolver.hpp> |
23 | | #include <osl/diagnose.h> |
24 | | #include <comphelper/sequence.hxx> |
25 | | #include <controls/eventcontainer.hxx> |
26 | | #include <helper/property.hxx> |
27 | | #include <algorithm> |
28 | | #include <functional> |
29 | | #include <utility> |
30 | | |
31 | | namespace |
32 | | { |
33 | | enum GcmPropertyId : sal_Int32 |
34 | | { |
35 | | GCM_PROPERTY_ID_POS_X = 1, |
36 | | GCM_PROPERTY_ID_POS_Y = 2, |
37 | | GCM_PROPERTY_ID_WIDTH = 3, |
38 | | GCM_PROPERTY_ID_HEIGHT = 4, |
39 | | GCM_PROPERTY_ID_NAME = 5, |
40 | | GCM_PROPERTY_ID_TABINDEX = 6, |
41 | | GCM_PROPERTY_ID_STEP = 7, |
42 | | GCM_PROPERTY_ID_TAG = 8, |
43 | | GCM_PROPERTY_ID_RESOURCERESOLVER = 9 |
44 | | }; |
45 | | } |
46 | | |
47 | | constexpr OUStringLiteral GCM_PROPERTY_POS_X = u"PositionX"; |
48 | | constexpr OUStringLiteral GCM_PROPERTY_POS_Y = u"PositionY"; |
49 | | constexpr OUStringLiteral GCM_PROPERTY_WIDTH = u"Width"; |
50 | | constexpr OUStringLiteral GCM_PROPERTY_HEIGHT = u"Height"; |
51 | | constexpr OUStringLiteral GCM_PROPERTY_NAME = u"Name"; |
52 | | constexpr OUStringLiteral GCM_PROPERTY_TABINDEX = u"TabIndex"; |
53 | | constexpr OUStringLiteral GCM_PROPERTY_STEP = u"Step"; |
54 | | constexpr OUStringLiteral GCM_PROPERTY_TAG = u"Tag"; |
55 | | constexpr OUStringLiteral GCM_PROPERTY_RESOURCERESOLVER = u"ResourceResolver"; |
56 | | |
57 | 0 | #define DEFAULT_ATTRIBS() PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT |
58 | | |
59 | | |
60 | | // namespace toolkit |
61 | | // { |
62 | | |
63 | | |
64 | | using namespace ::com::sun::star; |
65 | | using namespace ::com::sun::star::uno; |
66 | | using namespace ::com::sun::star::lang; |
67 | | using namespace ::com::sun::star::beans; |
68 | | using namespace ::com::sun::star::util; |
69 | | using namespace ::com::sun::star::container; |
70 | | using namespace ::comphelper; |
71 | | |
72 | | |
73 | | //= OGeometryControlModel_Base |
74 | | |
75 | | |
76 | | OGeometryControlModel_Base::OGeometryControlModel_Base(css::uno::XAggregation* _pAggregateInstance) |
77 | 0 | :OPropertySetAggregationHelper( m_aBHelper ) |
78 | 0 | ,OPropertyContainer( m_aBHelper ) |
79 | 0 | ,OGCM_Base( m_aMutex ) |
80 | 0 | ,m_nPosX(0) |
81 | 0 | ,m_nPosY(0) |
82 | 0 | ,m_nWidth(0) |
83 | 0 | ,m_nHeight(0) |
84 | 0 | ,m_nTabIndex(-1) |
85 | 0 | ,m_nStep(0) |
86 | 0 | ,m_bCloneable(false) |
87 | 0 | { |
88 | 0 | OSL_ENSURE(nullptr != _pAggregateInstance, "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid aggregate!"); |
89 | |
|
90 | 0 | osl_atomic_increment(&m_refCount); |
91 | 0 | { |
92 | 0 | m_xAggregate = _pAggregateInstance; |
93 | |
|
94 | 0 | { // check if the aggregate is clonable |
95 | 0 | Reference< XCloneable > xCloneAccess(m_xAggregate, UNO_QUERY); |
96 | 0 | m_bCloneable = xCloneAccess.is(); |
97 | 0 | } |
98 | |
|
99 | 0 | setAggregation(m_xAggregate); |
100 | 0 | m_xAggregate->setDelegator(getXWeak()); |
101 | 0 | } |
102 | 0 | osl_atomic_decrement(&m_refCount); |
103 | |
|
104 | 0 | registerProperties(); |
105 | 0 | } |
106 | | |
107 | | |
108 | | OGeometryControlModel_Base::OGeometryControlModel_Base(Reference< XCloneable >& _rxAggregateInstance) |
109 | 0 | :OPropertySetAggregationHelper( m_aBHelper ) |
110 | 0 | ,OPropertyContainer( m_aBHelper ) |
111 | 0 | ,OGCM_Base( m_aMutex ) |
112 | 0 | ,m_nPosX(0) |
113 | 0 | ,m_nPosY(0) |
114 | 0 | ,m_nWidth(0) |
115 | 0 | ,m_nHeight(0) |
116 | 0 | ,m_nTabIndex(-1) |
117 | 0 | ,m_nStep(0) |
118 | 0 | ,m_bCloneable(_rxAggregateInstance.is()) |
119 | 0 | { |
120 | 0 | osl_atomic_increment(&m_refCount); |
121 | 0 | { |
122 | 0 | { |
123 | | // ensure that the temporary gets destructed NOW |
124 | 0 | m_xAggregate.set(_rxAggregateInstance, UNO_QUERY); |
125 | 0 | } |
126 | 0 | OSL_ENSURE(m_xAggregate.is(), "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid object given!"); |
127 | | |
128 | | // now the aggregate has a ref count of 2, but before setting the delegator it must be 1 |
129 | 0 | _rxAggregateInstance.clear(); |
130 | | // now it should be the 1 we need here ... |
131 | |
|
132 | 0 | setAggregation(m_xAggregate); |
133 | 0 | m_xAggregate->setDelegator(getXWeak()); |
134 | 0 | } |
135 | 0 | osl_atomic_decrement(&m_refCount); |
136 | |
|
137 | 0 | registerProperties(); |
138 | 0 | } |
139 | | |
140 | | |
141 | | Sequence< Type > SAL_CALL OGeometryControlModel_Base::getTypes( ) |
142 | 0 | { |
143 | | // our own types |
144 | 0 | Sequence< Type > aTypes = ::comphelper::concatSequences( |
145 | 0 | OPropertySetAggregationHelper::getTypes(), |
146 | 0 | getBaseTypes(), |
147 | 0 | OGCM_Base::getTypes() |
148 | 0 | ); |
149 | |
|
150 | 0 | if ( m_xAggregate.is() ) |
151 | 0 | { |
152 | | // retrieve the types of the aggregate |
153 | 0 | Reference< XTypeProvider > xAggregateTypeProv; |
154 | 0 | m_xAggregate->queryAggregation( cppu::UnoType<decltype(xAggregateTypeProv)>::get() ) >>= xAggregateTypeProv; |
155 | 0 | OSL_ENSURE( xAggregateTypeProv.is(), "OGeometryControlModel_Base::getTypes: aggregate should be a type provider!" ); |
156 | 0 | Sequence< Type > aAggTypes; |
157 | 0 | if ( xAggregateTypeProv.is() ) |
158 | 0 | aAggTypes = xAggregateTypeProv->getTypes(); |
159 | | |
160 | | // concat the sequences |
161 | 0 | sal_Int32 nOldSize = aTypes.getLength(); |
162 | 0 | aTypes.realloc( nOldSize + aAggTypes.getLength() ); |
163 | 0 | ::std::copy( |
164 | 0 | std::cbegin(aAggTypes), |
165 | 0 | std::cend(aAggTypes), |
166 | 0 | aTypes.getArray() + nOldSize |
167 | 0 | ); |
168 | 0 | } |
169 | |
|
170 | 0 | return aTypes; |
171 | 0 | } |
172 | | |
173 | | |
174 | | void OGeometryControlModel_Base::registerProperties() |
175 | 0 | { |
176 | | // register our members for the property handling of the OPropertyContainer |
177 | 0 | registerProperty(GCM_PROPERTY_POS_X, GCM_PROPERTY_ID_POS_X, DEFAULT_ATTRIBS(), &m_nPosX, cppu::UnoType<decltype(m_nPosX)>::get()); |
178 | 0 | registerProperty(GCM_PROPERTY_POS_Y, GCM_PROPERTY_ID_POS_Y, DEFAULT_ATTRIBS(), &m_nPosY, cppu::UnoType<decltype(m_nPosY)>::get()); |
179 | 0 | registerProperty(GCM_PROPERTY_WIDTH, GCM_PROPERTY_ID_WIDTH, DEFAULT_ATTRIBS(), &m_nWidth, cppu::UnoType<decltype(m_nWidth)>::get()); |
180 | 0 | registerProperty(GCM_PROPERTY_HEIGHT, GCM_PROPERTY_ID_HEIGHT, DEFAULT_ATTRIBS(), &m_nHeight, cppu::UnoType<decltype(m_nHeight)>::get()); |
181 | 0 | registerProperty(GCM_PROPERTY_NAME, GCM_PROPERTY_ID_NAME, DEFAULT_ATTRIBS(), &m_aName, cppu::UnoType<decltype(m_aName)>::get()); |
182 | 0 | registerProperty(GCM_PROPERTY_TABINDEX, GCM_PROPERTY_ID_TABINDEX, DEFAULT_ATTRIBS(), &m_nTabIndex, cppu::UnoType<decltype(m_nTabIndex)>::get()); |
183 | 0 | registerProperty(GCM_PROPERTY_STEP, GCM_PROPERTY_ID_STEP, DEFAULT_ATTRIBS(), &m_nStep, cppu::UnoType<decltype(m_nStep)>::get()); |
184 | 0 | registerProperty(GCM_PROPERTY_TAG, GCM_PROPERTY_ID_TAG, DEFAULT_ATTRIBS(), &m_aTag, cppu::UnoType<decltype(m_aTag)>::get()); |
185 | 0 | registerProperty(GCM_PROPERTY_RESOURCERESOLVER, GCM_PROPERTY_ID_RESOURCERESOLVER, DEFAULT_ATTRIBS(), &m_xStrResolver, cppu::UnoType<decltype(m_xStrResolver)>::get()); |
186 | 0 | } |
187 | | |
188 | | |
189 | | css::uno::Any OGeometryControlModel_Base::ImplGetDefaultValueByHandle(sal_Int32 nHandle) |
190 | 0 | { |
191 | 0 | css::uno::Any aDefault; |
192 | |
|
193 | 0 | switch ( nHandle ) |
194 | 0 | { |
195 | 0 | case GCM_PROPERTY_ID_POS_X: aDefault <<= sal_Int32(0); break; |
196 | 0 | case GCM_PROPERTY_ID_POS_Y: aDefault <<= sal_Int32(0); break; |
197 | 0 | case GCM_PROPERTY_ID_WIDTH: aDefault <<= sal_Int32(0); break; |
198 | 0 | case GCM_PROPERTY_ID_HEIGHT: aDefault <<= sal_Int32(0); break; |
199 | 0 | case GCM_PROPERTY_ID_NAME: aDefault <<= OUString(); break; |
200 | 0 | case GCM_PROPERTY_ID_TABINDEX: aDefault <<= sal_Int16(-1); break; |
201 | 0 | case GCM_PROPERTY_ID_STEP: aDefault <<= sal_Int32(0); break; |
202 | 0 | case GCM_PROPERTY_ID_TAG: aDefault <<= OUString(); break; |
203 | 0 | case GCM_PROPERTY_ID_RESOURCERESOLVER: aDefault <<= Reference< resource::XStringResourceResolver >(); break; |
204 | 0 | default: OSL_FAIL( "ImplGetDefaultValueByHandle - unknown Property" ); |
205 | 0 | } |
206 | | |
207 | 0 | return aDefault; |
208 | 0 | } |
209 | | |
210 | | |
211 | | css::uno::Any OGeometryControlModel_Base::ImplGetPropertyValueByHandle(sal_Int32 nHandle) const |
212 | 0 | { |
213 | 0 | css::uno::Any aValue; |
214 | |
|
215 | 0 | switch ( nHandle ) |
216 | 0 | { |
217 | 0 | case GCM_PROPERTY_ID_POS_X: aValue <<= m_nPosX; break; |
218 | 0 | case GCM_PROPERTY_ID_POS_Y: aValue <<= m_nPosY; break; |
219 | 0 | case GCM_PROPERTY_ID_WIDTH: aValue <<= m_nWidth; break; |
220 | 0 | case GCM_PROPERTY_ID_HEIGHT: aValue <<= m_nHeight; break; |
221 | 0 | case GCM_PROPERTY_ID_NAME: aValue <<= m_aName; break; |
222 | 0 | case GCM_PROPERTY_ID_TABINDEX: aValue <<= m_nTabIndex; break; |
223 | 0 | case GCM_PROPERTY_ID_STEP: aValue <<= m_nStep; break; |
224 | 0 | case GCM_PROPERTY_ID_TAG: aValue <<= m_aTag; break; |
225 | 0 | case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue <<= m_xStrResolver; break; |
226 | 0 | default: OSL_FAIL( "ImplGetPropertyValueByHandle - unknown Property" ); |
227 | 0 | } |
228 | | |
229 | 0 | return aValue; |
230 | 0 | } |
231 | | |
232 | | |
233 | | void OGeometryControlModel_Base::ImplSetPropertyValueByHandle(sal_Int32 nHandle, const css::uno::Any& aValue) |
234 | 0 | { |
235 | 0 | switch ( nHandle ) |
236 | 0 | { |
237 | 0 | case GCM_PROPERTY_ID_POS_X: aValue >>= m_nPosX; break; |
238 | 0 | case GCM_PROPERTY_ID_POS_Y: aValue >>= m_nPosY; break; |
239 | 0 | case GCM_PROPERTY_ID_WIDTH: aValue >>= m_nWidth; break; |
240 | 0 | case GCM_PROPERTY_ID_HEIGHT: aValue >>= m_nHeight; break; |
241 | 0 | case GCM_PROPERTY_ID_NAME: aValue >>= m_aName; break; |
242 | 0 | case GCM_PROPERTY_ID_TABINDEX: aValue >>= m_nTabIndex; break; |
243 | 0 | case GCM_PROPERTY_ID_STEP: aValue >>= m_nStep; break; |
244 | 0 | case GCM_PROPERTY_ID_TAG: aValue >>= m_aTag; break; |
245 | 0 | case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue >>= m_xStrResolver; break; |
246 | 0 | default: OSL_FAIL( "ImplSetPropertyValueByHandle - unknown Property" ); |
247 | 0 | } |
248 | 0 | } |
249 | | |
250 | | |
251 | | Any SAL_CALL OGeometryControlModel_Base::queryAggregation( const Type& _rType ) |
252 | 0 | { |
253 | 0 | Any aReturn; |
254 | 0 | if (_rType.equals(cppu::UnoType<XCloneable>::get()) && !m_bCloneable) |
255 | | // somebody is asking for the XCloneable interface, but our aggregate does not support it |
256 | | // -> outta here |
257 | | // (need this extra check, cause OGCM_Base::queryAggregation would return this interface |
258 | | // in every case) |
259 | 0 | return aReturn; |
260 | | |
261 | 0 | aReturn = OGCM_Base::queryAggregation(_rType); |
262 | | // the basic interfaces (XInterface, XAggregation etc) |
263 | |
|
264 | 0 | if (!aReturn.hasValue()) |
265 | 0 | aReturn = OPropertySetAggregationHelper::queryInterface(_rType); |
266 | | // the property set related interfaces |
267 | |
|
268 | 0 | if (!aReturn.hasValue() && m_xAggregate.is()) |
269 | 0 | aReturn = m_xAggregate->queryAggregation(_rType); |
270 | | // the interfaces our aggregate can provide |
271 | |
|
272 | 0 | return aReturn; |
273 | 0 | } |
274 | | |
275 | | |
276 | | Any SAL_CALL OGeometryControlModel_Base::queryInterface( const Type& _rType ) |
277 | 0 | { |
278 | 0 | return OGCM_Base::queryInterface(_rType); |
279 | 0 | } |
280 | | |
281 | | |
282 | | void SAL_CALL OGeometryControlModel_Base::acquire( ) noexcept |
283 | 0 | { |
284 | 0 | OGCM_Base::acquire(); |
285 | 0 | } |
286 | | |
287 | | |
288 | | void SAL_CALL OGeometryControlModel_Base::release( ) noexcept |
289 | 0 | { |
290 | 0 | OGCM_Base::release(); |
291 | 0 | } |
292 | | |
293 | | |
294 | | void OGeometryControlModel_Base::releaseAggregation() |
295 | 0 | { |
296 | | // release the aggregate (_before_ clearing m_xAggregate) |
297 | 0 | if (m_xAggregate.is()) |
298 | 0 | m_xAggregate->setDelegator(nullptr); |
299 | 0 | setAggregation(nullptr); |
300 | 0 | } |
301 | | |
302 | | |
303 | | OGeometryControlModel_Base::~OGeometryControlModel_Base() |
304 | 0 | { |
305 | 0 | releaseAggregation(); |
306 | 0 | } |
307 | | |
308 | | |
309 | | sal_Bool SAL_CALL OGeometryControlModel_Base::convertFastPropertyValue(Any& _rConvertedValue, Any& _rOldValue, |
310 | | sal_Int32 _nHandle, const Any& _rValue) |
311 | 0 | { |
312 | 0 | return OPropertyContainer::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue); |
313 | 0 | } |
314 | | |
315 | | |
316 | | void SAL_CALL OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) |
317 | 0 | { |
318 | 0 | OPropertyContainer::setFastPropertyValue_NoBroadcast(_nHandle, _rValue); |
319 | 0 | } |
320 | | |
321 | | |
322 | | void SAL_CALL OGeometryControlModel_Base::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const |
323 | 0 | { |
324 | 0 | OPropertyArrayAggregationHelper& rPH = static_cast<OPropertyArrayAggregationHelper&>(const_cast<OGeometryControlModel_Base*>(this)->getInfoHelper()); |
325 | 0 | OUString sPropName; |
326 | 0 | sal_Int32 nOriginalHandle = -1; |
327 | |
|
328 | 0 | if (rPH.fillAggregatePropertyInfoByHandle(&sPropName, &nOriginalHandle, _nHandle)) |
329 | 0 | OPropertySetAggregationHelper::getFastPropertyValue(_rValue, _nHandle); |
330 | 0 | else |
331 | 0 | OPropertyContainer::getFastPropertyValue(_rValue, _nHandle); |
332 | 0 | } |
333 | | |
334 | | |
335 | | css::beans::PropertyState OGeometryControlModel_Base::getPropertyStateByHandle(sal_Int32 nHandle) |
336 | 0 | { |
337 | 0 | css::uno::Any aValue = ImplGetPropertyValueByHandle( nHandle ); |
338 | 0 | css::uno::Any aDefault = ImplGetDefaultValueByHandle( nHandle ); |
339 | |
|
340 | 0 | return CompareProperties( aValue, aDefault ) ? css::beans::PropertyState_DEFAULT_VALUE : css::beans::PropertyState_DIRECT_VALUE; |
341 | 0 | } |
342 | | |
343 | | |
344 | | void OGeometryControlModel_Base::setPropertyToDefaultByHandle(sal_Int32 nHandle) |
345 | 0 | { |
346 | 0 | ImplSetPropertyValueByHandle( nHandle , ImplGetDefaultValueByHandle( nHandle ) ); |
347 | 0 | } |
348 | | |
349 | | |
350 | | css::uno::Any OGeometryControlModel_Base::getPropertyDefaultByHandle( sal_Int32 nHandle ) const |
351 | 0 | { |
352 | 0 | return ImplGetDefaultValueByHandle( nHandle ); |
353 | 0 | } |
354 | | |
355 | | |
356 | | Reference< XPropertySetInfo> SAL_CALL OGeometryControlModel_Base::getPropertySetInfo() |
357 | 0 | { |
358 | 0 | return OPropertySetAggregationHelper::createPropertySetInfo(getInfoHelper()); |
359 | 0 | } |
360 | | |
361 | | |
362 | | Reference< XCloneable > SAL_CALL OGeometryControlModel_Base::createClone( ) |
363 | 0 | { |
364 | 0 | OSL_ENSURE(m_bCloneable, "OGeometryControlModel_Base::createClone: invalid call!"); |
365 | 0 | if (!m_bCloneable) |
366 | 0 | return Reference< XCloneable >(); |
367 | | |
368 | | // let the aggregate create its own clone |
369 | | // the interface |
370 | 0 | Reference< XCloneable > xCloneAccess; |
371 | 0 | m_xAggregate->queryAggregation(cppu::UnoType<decltype(xCloneAccess)>::get()) >>= xCloneAccess; |
372 | 0 | OSL_ENSURE(xCloneAccess.is(), "OGeometryControlModel_Base::createClone: suspicious aggregate!"); |
373 | 0 | if (!xCloneAccess.is()) |
374 | 0 | return Reference< XCloneable >(); |
375 | | // the aggregate's clone |
376 | 0 | Reference< XCloneable > xAggregateClone = xCloneAccess->createClone(); |
377 | 0 | OSL_ENSURE(xAggregateClone.is(), "OGeometryControlModel_Base::createClone: suspicious return of the aggregate!"); |
378 | | |
379 | | // create a new wrapper aggregating this return value |
380 | 0 | rtl::Reference<OGeometryControlModel_Base> pOwnClone = createClone_Impl(xAggregateClone); |
381 | 0 | OSL_ENSURE(pOwnClone, "OGeometryControlModel_Base::createClone: invalid derivee behaviour!"); |
382 | 0 | OSL_ENSURE(!xAggregateClone.is(), "OGeometryControlModel_Base::createClone: invalid ctor behaviour!"); |
383 | | // should have been reset |
384 | | |
385 | | // set properties |
386 | 0 | pOwnClone->m_nPosX = m_nPosX; |
387 | 0 | pOwnClone->m_nPosY = m_nPosY; |
388 | 0 | pOwnClone->m_nWidth = m_nWidth; |
389 | 0 | pOwnClone->m_nHeight = m_nHeight; |
390 | 0 | pOwnClone->m_aName = m_aName; |
391 | 0 | pOwnClone->m_nTabIndex = m_nTabIndex; |
392 | 0 | pOwnClone->m_nStep = m_nStep; |
393 | 0 | pOwnClone->m_aTag = m_aTag; |
394 | | |
395 | | |
396 | | // Clone event container |
397 | 0 | Reference< css::script::XScriptEventsSupplier > xEventsSupplier = |
398 | 0 | static_cast< css::script::XScriptEventsSupplier* >( this ); |
399 | |
|
400 | 0 | if( xEventsSupplier.is() ) |
401 | 0 | { |
402 | 0 | Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents(); |
403 | 0 | Reference< XNameContainer > xCloneEventCont = pOwnClone->getEvents(); |
404 | |
|
405 | 0 | const css::uno::Sequence< OUString > aNames = |
406 | 0 | xEventCont->getElementNames(); |
407 | |
|
408 | 0 | for( const OUString& aName : aNames ) |
409 | 0 | { |
410 | 0 | css::uno::Any aElement = xEventCont->getByName( aName ); |
411 | 0 | xCloneEventCont->insertByName( aName, aElement ); |
412 | 0 | } |
413 | 0 | } |
414 | |
|
415 | 0 | return pOwnClone; |
416 | 0 | } |
417 | | |
418 | | |
419 | | Reference< XNameContainer > SAL_CALL OGeometryControlModel_Base::getEvents() |
420 | 0 | { |
421 | 0 | if( !mxEventContainer.is() ) |
422 | 0 | mxEventContainer = new toolkit::ScriptEventContainer(); |
423 | 0 | return mxEventContainer; |
424 | 0 | } |
425 | | |
426 | | |
427 | | void SAL_CALL OGeometryControlModel_Base::disposing() |
428 | 0 | { |
429 | 0 | OGCM_Base::disposing(); |
430 | 0 | OPropertySetAggregationHelper::disposing(); |
431 | |
|
432 | 0 | if (auto xComp = query_aggregation<XComponent>(m_xAggregate)) |
433 | 0 | xComp->dispose(); |
434 | 0 | } |
435 | | |
436 | | |
437 | | //= OCommonGeometryControlModel |
438 | | |
439 | | |
440 | | typedef std::unordered_map< OUString, sal_Int32 > HashMapString2Int; |
441 | | typedef std::vector< css::uno::Sequence< css::beans::Property > > PropSeqArray; |
442 | | typedef std::vector< ::std::vector< sal_Int32 > > IntArrayArray; |
443 | | |
444 | | // for creating class-unique PropertySetInfo's, we need some info: |
445 | | namespace { HashMapString2Int gServiceSpecifierMap; } |
446 | | // this one maps from a String, which is the service specifier for our |
447 | | // aggregate, to a unique id |
448 | | |
449 | | namespace { PropSeqArray gAggregateProperties; } |
450 | | // this one contains the properties which belong to all the unique ids |
451 | | // in ServiceSpecifierMap |
452 | | |
453 | | namespace { IntArrayArray gAmbiguousPropertyIds; } |
454 | | // the ids of the properties which we as well as our aggregate supply |
455 | | // For such props, we let our base class handle them, and whenever such |
456 | | // a prop is set, we forward this to our aggregate. |
457 | | |
458 | | // With this, we can ensure that two instances of this class share the |
459 | | // same PropertySetInfo if and only if both aggregates have the same |
460 | | // service specifier. |
461 | | |
462 | | |
463 | | OCommonGeometryControlModel::OCommonGeometryControlModel( Reference< XCloneable >& _rxAgg, OUString _aServiceSpecifier ) |
464 | 0 | :OGeometryControlModel_Base( _rxAgg ) |
465 | 0 | ,m_sServiceSpecifier(std::move( _aServiceSpecifier )) |
466 | 0 | ,m_nPropertyMapId( 0 ) |
467 | 0 | { |
468 | 0 | Reference< XPropertySetInfo > xPI; |
469 | 0 | if ( m_xAggregateSet.is() ) |
470 | 0 | xPI = m_xAggregateSet->getPropertySetInfo(); |
471 | 0 | if ( !xPI.is() ) |
472 | 0 | { |
473 | 0 | releaseAggregation(); |
474 | 0 | throw IllegalArgumentException(); |
475 | 0 | } |
476 | | |
477 | 0 | HashMapString2Int::iterator aPropMapIdPos = gServiceSpecifierMap.find( m_sServiceSpecifier ); |
478 | 0 | if ( gServiceSpecifierMap.end() == aPropMapIdPos ) |
479 | 0 | { |
480 | 0 | m_nPropertyMapId = gAggregateProperties.size(); |
481 | 0 | gAggregateProperties.push_back( xPI->getProperties() ); |
482 | 0 | gAmbiguousPropertyIds.emplace_back( ); |
483 | |
|
484 | 0 | gServiceSpecifierMap[ m_sServiceSpecifier ] = m_nPropertyMapId; |
485 | 0 | } |
486 | 0 | else |
487 | 0 | m_nPropertyMapId = aPropMapIdPos->second; |
488 | 0 | } |
489 | | |
490 | | namespace { |
491 | | |
492 | | struct PropertyNameLess |
493 | | { |
494 | | bool operator()( const Property& _rLHS, const Property& _rRHS ) |
495 | 0 | { |
496 | 0 | return _rLHS.Name < _rRHS.Name; |
497 | 0 | } |
498 | | }; |
499 | | |
500 | | |
501 | | struct PropertyNameEqual |
502 | | { |
503 | | const OUString& m_rCompare; |
504 | 0 | explicit PropertyNameEqual( const OUString& _rCompare ) : m_rCompare( _rCompare ) { } |
505 | | |
506 | | bool operator()( const Property& _rLHS ) |
507 | 0 | { |
508 | 0 | return _rLHS.Name == m_rCompare; |
509 | 0 | } |
510 | | }; |
511 | | |
512 | | } |
513 | | |
514 | | ::cppu::IPropertyArrayHelper* OCommonGeometryControlModel::createArrayHelper( sal_Int32 _nId ) const |
515 | 0 | { |
516 | 0 | OSL_ENSURE( _nId == m_nPropertyMapId, "OCommonGeometryControlModel::createArrayHelper: invalid argument!" ); |
517 | 0 | OSL_ENSURE( _nId < static_cast<sal_Int32>(gAggregateProperties.size()), "OCommonGeometryControlModel::createArrayHelper: invalid status info (1)!" ); |
518 | 0 | OSL_ENSURE( _nId < static_cast<sal_Int32>(gAmbiguousPropertyIds.size()), "OCommonGeometryControlModel::createArrayHelper: invalid status info (2)!" ); |
519 | | |
520 | | // our own properties |
521 | 0 | Sequence< Property > aProps; |
522 | 0 | OPropertyContainer::describeProperties( aProps ); |
523 | | |
524 | | // the aggregate properties |
525 | 0 | Sequence< Property > aAggregateProps = gAggregateProperties[ _nId ]; |
526 | | |
527 | | // look for duplicates, and remember them |
528 | 0 | IntArrayArray::value_type& rDuplicateIds = gAmbiguousPropertyIds[ _nId ]; |
529 | | // for this, sort the aggregate properties |
530 | 0 | auto [begin, end] = asNonConstRange(aAggregateProps); |
531 | 0 | ::std::sort( |
532 | 0 | begin, |
533 | 0 | end, |
534 | 0 | PropertyNameLess() |
535 | 0 | ); |
536 | | |
537 | | // now loop through our own props |
538 | 0 | for (const Property& rProp : aProps) |
539 | 0 | { |
540 | | // look for the current property in the properties of our aggregate |
541 | 0 | const Property* pAggPropPos = ::std::find_if( std::cbegin(aAggregateProps), std::cend(aAggregateProps), PropertyNameEqual( rProp.Name ) ); |
542 | 0 | if ( pAggPropPos != std::cend(aAggregateProps) ) |
543 | 0 | { // found a duplicate |
544 | | // -> remove from the aggregate property sequence |
545 | 0 | ::comphelper::removeElementAt( aAggregateProps, pAggPropPos - std::cbegin(aAggregateProps) ); |
546 | | |
547 | | // and additionally, remember the id of this property |
548 | 0 | rDuplicateIds.push_back( rProp.Handle ); |
549 | 0 | } |
550 | 0 | } |
551 | | |
552 | | // now, finally, sort the duplicates |
553 | 0 | ::std::sort( rDuplicateIds.begin(), rDuplicateIds.end(), ::std::less< sal_Int32 >() ); |
554 | |
|
555 | 0 | return new OPropertyArrayAggregationHelper(aProps, aAggregateProps); |
556 | 0 | } |
557 | | |
558 | | |
559 | | ::cppu::IPropertyArrayHelper& SAL_CALL OCommonGeometryControlModel::getInfoHelper() |
560 | 0 | { |
561 | 0 | return *getArrayHelper( m_nPropertyMapId ); |
562 | 0 | } |
563 | | |
564 | | |
565 | | rtl::Reference<OGeometryControlModel_Base> OCommonGeometryControlModel::createClone_Impl( Reference< XCloneable >& _rxAggregateInstance ) |
566 | 0 | { |
567 | 0 | return new OCommonGeometryControlModel( _rxAggregateInstance, m_sServiceSpecifier ); |
568 | 0 | } |
569 | | |
570 | | Sequence< sal_Int8 > SAL_CALL OCommonGeometryControlModel::getImplementationId( ) |
571 | 0 | { |
572 | 0 | return css::uno::Sequence<sal_Int8>(); |
573 | 0 | } |
574 | | |
575 | | namespace { |
576 | | |
577 | | struct Int32Equal |
578 | | { |
579 | | sal_Int32 m_nCompare; |
580 | 0 | explicit Int32Equal( sal_Int32 _nCompare ) : m_nCompare( _nCompare ) { } |
581 | | |
582 | | bool operator()( sal_Int32 _nLHS ) |
583 | 0 | { |
584 | 0 | return _nLHS == m_nCompare; |
585 | 0 | } |
586 | | }; |
587 | | |
588 | | } |
589 | | |
590 | | void SAL_CALL OCommonGeometryControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) |
591 | 0 | { |
592 | 0 | OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast( _nHandle, _rValue ); |
593 | | |
594 | | // look if this id is one we recognized as duplicate |
595 | 0 | IntArrayArray::value_type& rDuplicateIds = gAmbiguousPropertyIds[ m_nPropertyMapId ]; |
596 | |
|
597 | 0 | if ( std::any_of(rDuplicateIds.begin(), rDuplicateIds.end(), Int32Equal( _nHandle )) ) |
598 | 0 | { |
599 | | // yes, it is such a property |
600 | 0 | OUString sPropName; |
601 | 0 | sal_Int16 nAttributes(0); |
602 | 0 | static_cast< OPropertyArrayAggregationHelper* >( getArrayHelper( m_nPropertyMapId ) )->fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle ); |
603 | |
|
604 | 0 | if ( m_xAggregateSet.is() && !sPropName.isEmpty() ) |
605 | 0 | m_xAggregateSet->setPropertyValue( sPropName, _rValue ); |
606 | 0 | } |
607 | 0 | } |
608 | | |
609 | | |
610 | | // } // namespace toolkit |
611 | | |
612 | | |
613 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |