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