merge the formfield patch from ooo-build
[ooovba.git] / toolkit / source / controls / geometrycontrolmodel.cxx
blob75994fdffd9375f2784c7b01060e249fc0b137c4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: geometrycontrolmodel.cxx,v $
10 * $Revision: 1.25 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_toolkit.hxx"
33 #include "toolkit/controls/geometrycontrolmodel.hxx"
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <osl/diagnose.h>
37 #include <rtl/instance.hxx>
38 #include <comphelper/property.hxx>
39 #include <comphelper/sequence.hxx>
40 #ifndef _COM_SUN_STAR_XNAMECONTAINER_HPP_
41 #include <toolkit/controls/eventcontainer.hxx>
42 #endif
43 #include <toolkit/helper/property.hxx>
44 #include <tools/debug.hxx>
45 #include <algorithm>
46 #include <functional>
47 #include <comphelper/sequence.hxx>
50 #define GCM_PROPERTY_ID_POS_X 1
51 #define GCM_PROPERTY_ID_POS_Y 2
52 #define GCM_PROPERTY_ID_WIDTH 3
53 #define GCM_PROPERTY_ID_HEIGHT 4
54 #define GCM_PROPERTY_ID_NAME 5
55 #define GCM_PROPERTY_ID_TABINDEX 6
56 #define GCM_PROPERTY_ID_STEP 7
57 #define GCM_PROPERTY_ID_TAG 8
58 #define GCM_PROPERTY_ID_RESOURCERESOLVER 9
60 #define GCM_PROPERTY_POS_X ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionX"))
61 #define GCM_PROPERTY_POS_Y ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("PositionY"))
62 #define GCM_PROPERTY_WIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Width"))
63 #define GCM_PROPERTY_HEIGHT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Height"))
64 #define GCM_PROPERTY_NAME ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name"))
65 #define GCM_PROPERTY_TABINDEX ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TabIndex"))
66 #define GCM_PROPERTY_STEP ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Step"))
67 #define GCM_PROPERTY_TAG ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tag"))
68 #define GCM_PROPERTY_RESOURCERESOLVER ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ResourceResolver"))
70 #define DEFAULT_ATTRIBS() PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT
72 //........................................................................
73 // namespace toolkit
74 // {
75 //........................................................................
77 using namespace ::com::sun::star;
78 using namespace ::com::sun::star::uno;
79 using namespace ::com::sun::star::lang;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::util;
82 using namespace ::com::sun::star::container;
83 using namespace ::comphelper;
85 //====================================================================
86 //= OGeometryControlModel_Base
87 //====================================================================
88 //--------------------------------------------------------------------
89 OGeometryControlModel_Base::OGeometryControlModel_Base(::com::sun::star::uno::XAggregation* _pAggregateInstance)
90 :OPropertySetAggregationHelper( m_aBHelper )
91 ,OPropertyContainer( m_aBHelper )
92 ,OGCM_Base( m_aMutex )
93 ,m_nPosX(0)
94 ,m_nPosY(0)
95 ,m_nWidth(0)
96 ,m_nHeight(0)
97 ,m_nTabIndex(-1)
98 ,m_nStep(0)
99 ,m_bCloneable(sal_False)
101 OSL_ENSURE(NULL != _pAggregateInstance, "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid aggregate!");
103 increment(m_refCount);
105 m_xAggregate = _pAggregateInstance;
107 { // check if the aggregat is cloneable
108 Reference< XCloneable > xCloneAccess(m_xAggregate, UNO_QUERY);
109 m_bCloneable = xCloneAccess.is();
112 setAggregation(m_xAggregate);
113 m_xAggregate->setDelegator(static_cast< XWeak* >(this));
115 decrement(m_refCount);
117 registerProperties();
120 //--------------------------------------------------------------------
121 OGeometryControlModel_Base::OGeometryControlModel_Base(Reference< XCloneable >& _rxAggregateInstance)
122 :OPropertySetAggregationHelper( m_aBHelper )
123 ,OPropertyContainer( m_aBHelper )
124 ,OGCM_Base( m_aMutex )
125 ,m_nPosX(0)
126 ,m_nPosY(0)
127 ,m_nWidth(0)
128 ,m_nHeight(0)
129 ,m_nTabIndex(-1)
130 ,m_nStep(0)
131 ,m_bCloneable(_rxAggregateInstance.is())
133 increment(m_refCount);
136 // ensure that the temporary gets destructed NOW
137 m_xAggregate = Reference< XAggregation >(_rxAggregateInstance, UNO_QUERY);
139 OSL_ENSURE(m_xAggregate.is(), "OGeometryControlModel_Base::OGeometryControlModel_Base: invalid object given!");
141 // now the aggregate has a ref count of 2, but before setting the delegator it must be 1
142 _rxAggregateInstance.clear();
143 // now it should be the 1 we need here ...
145 setAggregation(m_xAggregate);
146 m_xAggregate->setDelegator(static_cast< XWeak* >(this));
148 decrement(m_refCount);
150 registerProperties();
153 //--------------------------------------------------------------------
154 Sequence< Type > SAL_CALL OGeometryControlModel_Base::getTypes( ) throw (RuntimeException)
156 // our own types
157 Sequence< Type > aTypes = ::comphelper::concatSequences(
158 OPropertySetAggregationHelper::getTypes(),
159 OPropertyContainer::getTypes(),
160 OGCM_Base::getTypes()
163 if ( m_xAggregate.is() )
165 // retrieve the types of the aggregate
166 Reference< XTypeProvider > xAggregateTypeProv;
167 m_xAggregate->queryAggregation( ::getCppuType( &xAggregateTypeProv ) ) >>= xAggregateTypeProv;
168 OSL_ENSURE( xAggregateTypeProv.is(), "OGeometryControlModel_Base::getTypes: aggregate should be a type provider!" );
169 Sequence< Type > aAggTypes;
170 if ( xAggregateTypeProv.is() )
171 aAggTypes = xAggregateTypeProv->getTypes();
173 // concat the sequences
174 sal_Int32 nOldSize = aTypes.getLength();
175 aTypes.realloc( nOldSize + aAggTypes.getLength() );
176 ::std::copy(
177 aAggTypes.getConstArray(),
178 aAggTypes.getConstArray() + aAggTypes.getLength(),
179 aTypes.getArray() + nOldSize
183 return aTypes;
186 //--------------------------------------------------------------------
187 void OGeometryControlModel_Base::registerProperties()
189 // register our members for the property handling of the OPropertyContainer
190 registerProperty(GCM_PROPERTY_POS_X, GCM_PROPERTY_ID_POS_X, DEFAULT_ATTRIBS(), &m_nPosX, ::getCppuType(&m_nPosX));
191 registerProperty(GCM_PROPERTY_POS_Y, GCM_PROPERTY_ID_POS_Y, DEFAULT_ATTRIBS(), &m_nPosY, ::getCppuType(&m_nPosY));
192 registerProperty(GCM_PROPERTY_WIDTH, GCM_PROPERTY_ID_WIDTH, DEFAULT_ATTRIBS(), &m_nWidth, ::getCppuType(&m_nWidth));
193 registerProperty(GCM_PROPERTY_HEIGHT, GCM_PROPERTY_ID_HEIGHT, DEFAULT_ATTRIBS(), &m_nHeight, ::getCppuType(&m_nHeight));
194 registerProperty(GCM_PROPERTY_NAME, GCM_PROPERTY_ID_NAME, DEFAULT_ATTRIBS(), &m_aName, ::getCppuType(&m_aName));
195 registerProperty(GCM_PROPERTY_TABINDEX, GCM_PROPERTY_ID_TABINDEX, DEFAULT_ATTRIBS(), &m_nTabIndex, ::getCppuType(&m_nTabIndex));
196 registerProperty(GCM_PROPERTY_STEP, GCM_PROPERTY_ID_STEP, DEFAULT_ATTRIBS(), &m_nStep, ::getCppuType(&m_nStep));
197 registerProperty(GCM_PROPERTY_TAG, GCM_PROPERTY_ID_TAG, DEFAULT_ATTRIBS(), &m_aTag, ::getCppuType(&m_aTag));
198 registerProperty(GCM_PROPERTY_RESOURCERESOLVER, GCM_PROPERTY_ID_RESOURCERESOLVER, DEFAULT_ATTRIBS(), &m_xStrResolver, ::getCppuType(&m_xStrResolver));
201 //--------------------------------------------------------------------
202 ::com::sun::star::uno::Any OGeometryControlModel_Base::ImplGetDefaultValueByHandle(sal_Int32 nHandle) const
204 ::com::sun::star::uno::Any aDefault;
206 switch ( nHandle )
208 case GCM_PROPERTY_ID_POS_X: aDefault <<= (sal_Int32) 0; break;
209 case GCM_PROPERTY_ID_POS_Y: aDefault <<= (sal_Int32) 0; break;
210 case GCM_PROPERTY_ID_WIDTH: aDefault <<= (sal_Int32) 0; break;
211 case GCM_PROPERTY_ID_HEIGHT: aDefault <<= (sal_Int32) 0; break;
212 case GCM_PROPERTY_ID_NAME: aDefault <<= ::rtl::OUString(); break;
213 case GCM_PROPERTY_ID_TABINDEX: aDefault <<= (sal_Int16) -1; break;
214 case GCM_PROPERTY_ID_STEP: aDefault <<= (sal_Int32) 0; break;
215 case GCM_PROPERTY_ID_TAG: aDefault <<= ::rtl::OUString(); break;
216 case GCM_PROPERTY_ID_RESOURCERESOLVER: aDefault <<= Reference< resource::XStringResourceResolver >(); break;
217 default: DBG_ERROR( "ImplGetDefaultValueByHandle - unknown Property" );
220 return aDefault;
223 //--------------------------------------------------------------------
224 ::com::sun::star::uno::Any OGeometryControlModel_Base::ImplGetPropertyValueByHandle(sal_Int32 nHandle) const
226 ::com::sun::star::uno::Any aValue;
228 switch ( nHandle )
230 case GCM_PROPERTY_ID_POS_X: aValue <<= m_nPosX; break;
231 case GCM_PROPERTY_ID_POS_Y: aValue <<= m_nPosY; break;
232 case GCM_PROPERTY_ID_WIDTH: aValue <<= m_nWidth; break;
233 case GCM_PROPERTY_ID_HEIGHT: aValue <<= m_nHeight; break;
234 case GCM_PROPERTY_ID_NAME: aValue <<= m_aName; break;
235 case GCM_PROPERTY_ID_TABINDEX: aValue <<= m_nTabIndex; break;
236 case GCM_PROPERTY_ID_STEP: aValue <<= m_nStep; break;
237 case GCM_PROPERTY_ID_TAG: aValue <<= m_aTag; break;
238 case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue <<= m_xStrResolver; break;
239 default: DBG_ERROR( "ImplGetPropertyValueByHandle - unknown Property" );
242 return aValue;
245 //--------------------------------------------------------------------
246 void OGeometryControlModel_Base::ImplSetPropertyValueByHandle(sal_Int32 nHandle, const :: com::sun::star::uno::Any& aValue)
248 switch ( nHandle )
250 case GCM_PROPERTY_ID_POS_X: aValue >>= m_nPosX; break;
251 case GCM_PROPERTY_ID_POS_Y: aValue >>= m_nPosY; break;
252 case GCM_PROPERTY_ID_WIDTH: aValue >>= m_nWidth; break;
253 case GCM_PROPERTY_ID_HEIGHT: aValue >>= m_nHeight; break;
254 case GCM_PROPERTY_ID_NAME: aValue >>= m_aName; break;
255 case GCM_PROPERTY_ID_TABINDEX: aValue >>= m_nTabIndex; break;
256 case GCM_PROPERTY_ID_STEP: aValue >>= m_nStep; break;
257 case GCM_PROPERTY_ID_TAG: aValue >>= m_aTag; break;
258 case GCM_PROPERTY_ID_RESOURCERESOLVER: aValue >>= m_xStrResolver; break;
259 default: DBG_ERROR( "ImplSetPropertyValueByHandle - unknown Property" );
263 //--------------------------------------------------------------------
264 Any SAL_CALL OGeometryControlModel_Base::queryAggregation( const Type& _rType ) throw(RuntimeException)
266 Any aReturn;
267 if (_rType.equals(::getCppuType(static_cast< Reference< XCloneable>* >(NULL))) && !m_bCloneable)
268 // somebody is asking for the XCloneable interface, but our aggregate does not support it
269 // -> outta here
270 // (need this extra check, cause OGCM_Base::queryAggregation would return this interface
271 // in every case)
272 return aReturn;
274 aReturn = OGCM_Base::queryAggregation(_rType);
275 // the basic interfaces (XInterface, XAggregation etc)
277 if (!aReturn.hasValue())
278 aReturn = OPropertySetAggregationHelper::queryInterface(_rType);
279 // the property set related interfaces
281 if (!aReturn.hasValue() && m_xAggregate.is())
282 aReturn = m_xAggregate->queryAggregation(_rType);
283 // the interfaces our aggregate can provide
285 return aReturn;
288 //--------------------------------------------------------------------
289 Any SAL_CALL OGeometryControlModel_Base::queryInterface( const Type& _rType ) throw(RuntimeException)
291 return OGCM_Base::queryInterface(_rType);
294 //--------------------------------------------------------------------
295 void SAL_CALL OGeometryControlModel_Base::acquire( ) throw()
297 OGCM_Base::acquire();
300 //--------------------------------------------------------------------
301 void SAL_CALL OGeometryControlModel_Base::release( ) throw()
303 OGCM_Base::release();
306 //--------------------------------------------------------------------
307 void OGeometryControlModel_Base::releaseAggregation()
309 // release the aggregate (_before_ clearing m_xAggregate)
310 if (m_xAggregate.is())
311 m_xAggregate->setDelegator(NULL);
312 setAggregation(NULL);
315 //--------------------------------------------------------------------
316 OGeometryControlModel_Base::~OGeometryControlModel_Base()
318 releaseAggregation();
321 //--------------------------------------------------------------------
322 sal_Bool SAL_CALL OGeometryControlModel_Base::convertFastPropertyValue(Any& _rConvertedValue, Any& _rOldValue,
323 sal_Int32 _nHandle, const Any& _rValue) throw (IllegalArgumentException)
325 return OPropertyContainer::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
328 //--------------------------------------------------------------------
329 void SAL_CALL OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception)
331 OPropertyContainer::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
334 //--------------------------------------------------------------------
335 void SAL_CALL OGeometryControlModel_Base::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
337 OPropertyArrayAggregationHelper& rPH = static_cast<OPropertyArrayAggregationHelper&>(const_cast<OGeometryControlModel_Base*>(this)->getInfoHelper());
338 ::rtl::OUString sPropName;
339 sal_Int32 nOriginalHandle = -1;
341 if (rPH.fillAggregatePropertyInfoByHandle(&sPropName, &nOriginalHandle, _nHandle))
342 OPropertySetAggregationHelper::getFastPropertyValue(_rValue, _nHandle);
343 else
344 OPropertyContainer::getFastPropertyValue(_rValue, _nHandle);
347 //--------------------------------------------------------------------
348 ::com::sun::star::beans::PropertyState OGeometryControlModel_Base::getPropertyStateByHandle(sal_Int32 nHandle)
350 ::com::sun::star::uno::Any aValue = ImplGetPropertyValueByHandle( nHandle );
351 ::com::sun::star::uno::Any aDefault = ImplGetDefaultValueByHandle( nHandle );
353 return CompareProperties( aValue, aDefault ) ? ::com::sun::star::beans::PropertyState_DEFAULT_VALUE : ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
356 //--------------------------------------------------------------------
357 void OGeometryControlModel_Base::setPropertyToDefaultByHandle(sal_Int32 nHandle)
359 ImplSetPropertyValueByHandle( nHandle , ImplGetDefaultValueByHandle( nHandle ) );
362 //--------------------------------------------------------------------
363 ::com::sun::star::uno::Any OGeometryControlModel_Base::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
365 return ImplGetDefaultValueByHandle( nHandle );
368 //--------------------------------------------------------------------
369 Reference< XPropertySetInfo> SAL_CALL OGeometryControlModel_Base::getPropertySetInfo() throw(RuntimeException)
371 return OPropertySetAggregationHelper::createPropertySetInfo(getInfoHelper());
374 //--------------------------------------------------------------------
375 Reference< XCloneable > SAL_CALL OGeometryControlModel_Base::createClone( ) throw(RuntimeException)
377 OSL_ENSURE(m_bCloneable, "OGeometryControlModel_Base::createClone: invalid call!");
378 if (!m_bCloneable)
379 return Reference< XCloneable >();
381 // let the aggregate create it's own clone
382 // the interface
383 Reference< XCloneable > xCloneAccess;
384 m_xAggregate->queryAggregation(::getCppuType(&xCloneAccess)) >>= xCloneAccess;
385 OSL_ENSURE(xCloneAccess.is(), "OGeometryControlModel_Base::createClone: suspicious aggregate!");
386 if (!xCloneAccess.is())
387 return Reference< XCloneable >();
388 // the aggregate's clone
389 Reference< XCloneable > xAggregateClone = xCloneAccess->createClone();
390 OSL_ENSURE(xAggregateClone.is(), "OGeometryControlModel_Base::createClone: suspicious return of the aggregate!");
392 // create a new wrapper aggregating this return value
393 OGeometryControlModel_Base* pOwnClone = createClone_Impl(xAggregateClone);
394 OSL_ENSURE(pOwnClone, "OGeometryControlModel_Base::createClone: invalid derivee behaviour!");
395 OSL_ENSURE(!xAggregateClone.is(), "OGeometryControlModel_Base::createClone: invalid ctor behaviour!");
396 // should have been reset
398 // set properties
399 pOwnClone->m_nPosX = m_nPosX;
400 pOwnClone->m_nPosY = m_nPosY;
401 pOwnClone->m_nWidth = m_nWidth;
402 pOwnClone->m_nHeight = m_nHeight;
403 pOwnClone->m_aName = m_aName;
404 pOwnClone->m_nTabIndex = m_nTabIndex;
405 pOwnClone->m_nStep = m_nStep;
406 pOwnClone->m_aTag = m_aTag;
409 // Clone event container
410 Reference< ::com::sun::star::script::XScriptEventsSupplier > xEventsSupplier =
411 static_cast< ::com::sun::star::script::XScriptEventsSupplier* >( this );
412 Reference< ::com::sun::star::script::XScriptEventsSupplier > xCloneEventsSupplier =
413 static_cast< ::com::sun::star::script::XScriptEventsSupplier* >( pOwnClone );
415 if( xEventsSupplier.is() && xCloneEventsSupplier.is() )
417 Reference< XNameContainer > xEventCont = xEventsSupplier->getEvents();
418 Reference< XNameContainer > xCloneEventCont = xCloneEventsSupplier->getEvents();
420 ::com::sun::star::uno::Sequence< ::rtl::OUString > aNames =
421 xEventCont->getElementNames();
422 const ::rtl::OUString* pNames = aNames.getConstArray();
423 sal_Int32 i, nNameCount = aNames.getLength();
425 for( i = 0 ; i < nNameCount ; i++ )
427 ::rtl::OUString aName = pNames[ i ];
428 ::com::sun::star::uno::Any aElement = xEventCont->getByName( aName );
429 xCloneEventCont->insertByName( aName, aElement );
433 return pOwnClone;
436 //--------------------------------------------------------------------
437 Reference< XNameContainer > SAL_CALL OGeometryControlModel_Base::getEvents() throw(RuntimeException)
439 if( !mxEventContainer.is() )
440 mxEventContainer = (XNameContainer*)new toolkit::ScriptEventContainer();
441 return mxEventContainer;
444 //--------------------------------------------------------------------
445 void SAL_CALL OGeometryControlModel_Base::disposing()
447 OGCM_Base::disposing();
448 OPropertySetAggregationHelper::disposing();
450 Reference<XComponent> xComp;
451 if ( query_aggregation( m_xAggregate, xComp ) )
452 xComp->dispose();
455 //====================================================================
456 //= OCommonGeometryControlModel
457 //====================================================================
458 //--------------------------------------------------------------------
460 typedef ::std::hash_map< ::rtl::OUString, sal_Int32, ::comphelper::UStringHash > HashMapString2Int;
461 typedef ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > > PropSeqArray;
462 typedef ::std::vector< ::std::vector< sal_Int32 > > IntArrayArray;
464 // for creating class-unique PropertySetInfo's, we need some info:
465 namespace { struct ServiceSpecifierMap : public rtl::Static< HashMapString2Int, ServiceSpecifierMap > {}; }
466 // this one maps from a String, which is the service specifier for our
467 // aggregate, to a unique id
469 namespace { struct AggregateProperties : public rtl::Static< PropSeqArray, AggregateProperties > {}; }
470 // this one contains the properties which belong to all the unique ids
471 // in ServiceSpecifierMap
473 namespace { struct AmbiguousPropertyIds : public rtl::Static< IntArrayArray, AmbiguousPropertyIds > {}; }
474 // the ids of the properties which we as well as our aggregate supply
475 // For such props, we let our base class handle them, and whenever such
476 // a prop is set, we forward this to our aggregate.
478 // With this, we can ensure that two instances of this class share the
479 // same PropertySetInfo if and only if both aggregates have the same
480 // service specifier.
483 //--------------------------------------------------------------------
484 OCommonGeometryControlModel::OCommonGeometryControlModel( Reference< XCloneable >& _rxAgg, const ::rtl::OUString& _rServiceSpecifier )
485 :OGeometryControlModel_Base( _rxAgg )
486 ,m_sServiceSpecifier( _rServiceSpecifier )
487 ,m_nPropertyMapId( 0 )
489 Reference< XPropertySetInfo > xPI;
490 if ( m_xAggregateSet.is() )
491 xPI = m_xAggregateSet->getPropertySetInfo();
492 if ( !xPI.is() )
494 releaseAggregation();
495 throw IllegalArgumentException();
498 HashMapString2Int &rMap = ServiceSpecifierMap::get();
499 HashMapString2Int::iterator aPropMapIdPos = rMap.find( m_sServiceSpecifier );
500 if ( rMap.end() == aPropMapIdPos )
502 PropSeqArray &rAggProperties = AggregateProperties::get();
503 m_nPropertyMapId = rAggProperties.size();
504 rAggProperties.push_back( xPI->getProperties() );
505 AmbiguousPropertyIds::get().push_back( IntArrayArray::value_type() );
507 rMap[ m_sServiceSpecifier ] = m_nPropertyMapId;
509 else
510 m_nPropertyMapId = aPropMapIdPos->second;
513 //--------------------------------------------------------------------
514 struct PropertyNameLess : public ::std::binary_function< Property, Property, bool >
516 bool operator()( const Property& _rLHS, const Property& _rRHS )
518 return _rLHS.Name < _rRHS.Name ? true : false;
522 //--------------------------------------------------------------------
523 struct PropertyNameEqual : public ::std::unary_function< Property, bool >
525 const ::rtl::OUString& m_rCompare;
526 PropertyNameEqual( const ::rtl::OUString& _rCompare ) : m_rCompare( _rCompare ) { }
528 bool operator()( const Property& _rLHS )
530 return _rLHS.Name == m_rCompare ? true : false;
534 //--------------------------------------------------------------------
535 ::cppu::IPropertyArrayHelper* OCommonGeometryControlModel::createArrayHelper( sal_Int32 _nId ) const
537 OSL_ENSURE( _nId == m_nPropertyMapId, "OCommonGeometryControlModel::createArrayHelper: invalid argument!" );
538 OSL_ENSURE( _nId < (sal_Int32)AggregateProperties::get().size(), "OCommonGeometryControlModel::createArrayHelper: invalid status info (1)!" );
539 OSL_ENSURE( _nId < (sal_Int32)AmbiguousPropertyIds::get().size(), "OCommonGeometryControlModel::createArrayHelper: invalid status info (2)!" );
541 // our own properties
542 Sequence< Property > aProps;
543 OPropertyContainer::describeProperties( aProps );
545 // the aggregate properties
546 Sequence< Property > aAggregateProps;
547 aAggregateProps = AggregateProperties::get()[ _nId ];
549 // look for duplicates, and remember them
550 IntArrayArray::value_type& rDuplicateIds = AmbiguousPropertyIds::get()[ _nId ];
551 // for this, sort the aggregate properties
552 ::std::sort(
553 aAggregateProps.getArray(),
554 aAggregateProps.getArray() + aAggregateProps.getLength(),
555 PropertyNameLess()
557 const Property* pAggProps = aAggregateProps.getConstArray();
558 const Property* pAggPropsEnd = aAggregateProps.getConstArray() + aAggregateProps.getLength();
560 // now loop through our own props
561 const Property* pProp = aProps.getConstArray();
562 const Property* pPropEnd = aProps.getConstArray() + aProps.getLength();
563 while ( pProp < pPropEnd )
565 // look for the current property in the properties of our aggregate
566 const Property* pAggPropPos = ::std::find_if( pAggProps, pAggPropsEnd, PropertyNameEqual( pProp->Name ) );
567 if ( pAggPropPos != pAggPropsEnd )
568 { // found a duplicate
569 // -> remove from the aggregate property sequence
570 ::comphelper::removeElementAt( aAggregateProps, pAggPropPos - pAggProps );
571 // which means we have to adjust the pointers
572 pAggProps = aAggregateProps.getConstArray(),
573 pAggPropsEnd = aAggregateProps.getConstArray() + aAggregateProps.getLength(),
575 // and additionally, remember the id of this property
576 rDuplicateIds.push_back( pProp->Handle );
579 ++pProp;
582 // now, finally, sort the duplicates
583 ::std::sort( rDuplicateIds.begin(), rDuplicateIds.end(), ::std::less< sal_Int32 >() );
585 return new OPropertyArrayAggregationHelper(aProps, aAggregateProps);
588 //--------------------------------------------------------------------
589 ::cppu::IPropertyArrayHelper& SAL_CALL OCommonGeometryControlModel::getInfoHelper()
591 return *getArrayHelper( m_nPropertyMapId );
594 //--------------------------------------------------------------------
595 OGeometryControlModel_Base* OCommonGeometryControlModel::createClone_Impl( Reference< XCloneable >& _rxAggregateInstance )
597 return new OCommonGeometryControlModel( _rxAggregateInstance, m_sServiceSpecifier );
600 //--------------------------------------------------------------------
601 Sequence< sal_Int8 > SAL_CALL OCommonGeometryControlModel::getImplementationId( ) throw (RuntimeException)
603 static ::cppu::OImplementationId * pId = NULL;
604 if ( !pId )
606 ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
607 if ( !pId )
609 static ::cppu::OImplementationId s_aId;
610 pId = &s_aId;
613 return pId->getImplementationId();
616 //--------------------------------------------------------------------
617 struct Int32Equal : public ::std::unary_function< sal_Int32, bool >
619 sal_Int32 m_nCompare;
620 Int32Equal( sal_Int32 _nCompare ) : m_nCompare( _nCompare ) { }
622 bool operator()( sal_Int32 _nLHS )
624 return _nLHS == m_nCompare ? true : false;
628 //--------------------------------------------------------------------
629 void SAL_CALL OCommonGeometryControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
631 OGeometryControlModel_Base::setFastPropertyValue_NoBroadcast( _nHandle, _rValue );
633 // look if this id is one we recognized as duplicate
634 IntArrayArray::value_type& rDuplicateIds = AmbiguousPropertyIds::get()[ m_nPropertyMapId ];
636 IntArrayArray::value_type::const_iterator aPos = ::std::find_if(
637 rDuplicateIds.begin(),
638 rDuplicateIds.end(),
639 Int32Equal( _nHandle )
642 if ( rDuplicateIds.end() != aPos )
644 // yes, it is such a property
645 ::rtl::OUString sPropName;
646 sal_Int16 nAttributes(0);
647 static_cast< OPropertyArrayAggregationHelper* >( getArrayHelper( m_nPropertyMapId ) )->fillPropertyMembersByHandle( &sPropName, &nAttributes, _nHandle );
649 if ( m_xAggregateSet.is() && sPropName.getLength() )
650 m_xAggregateSet->setPropertyValue( sPropName, _rValue );
654 //........................................................................
655 // } // namespace toolkit
656 //........................................................................