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_svl.hxx" 26 27 #include <svl/itemprop.hxx> 28 #include <svl/itempool.hxx> 29 #include <svl/itemset.hxx> 30 #include <com/sun/star/beans/PropertyAttribute.hpp> 31 #include <hash_map> 32 /************************************************************************* 33 UNO III Implementation 34 *************************************************************************/ 35 using namespace com::sun::star; 36 using namespace com::sun::star::beans; 37 using namespace com::sun::star::lang; 38 using namespace com::sun::star::uno; 39 40 /*-- 16.02.2009 10:03:55--------------------------------------------------- 41 42 -----------------------------------------------------------------------*/ 43 44 struct equalOUString 45 { 46 bool operator()(const ::rtl::OUString& r1, const ::rtl::OUString& r2) const 47 { 48 return r1.equals( r2 ); 49 } 50 }; 51 52 typedef ::std::hash_map< ::rtl::OUString, 53 SfxItemPropertySimpleEntry, 54 ::rtl::OUStringHash, 55 equalOUString > SfxItemPropertyHashMap_t; 56 57 class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t 58 { 59 public: 60 mutable uno::Sequence< beans::Property > m_aPropSeq; 61 62 SfxItemPropertyMap_Impl(){} 63 SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource ); 64 }; 65 SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource ) 66 { 67 this->SfxItemPropertyHashMap_t::operator=( *pSource ); 68 m_aPropSeq = pSource->m_aPropSeq; 69 } 70 71 /*-- 16.02.2009 10:03:51--------------------------------------------------- 72 73 -----------------------------------------------------------------------*/ 74 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) : 75 m_pImpl( new SfxItemPropertyMap_Impl ) 76 { 77 while( pEntries->pName ) 78 { 79 ::rtl::OUString sEntry(pEntries->pName, pEntries->nNameLen, RTL_TEXTENCODING_ASCII_US ); 80 (*m_pImpl) [ sEntry ] = pEntries; 81 ++pEntries; 82 } 83 } 84 /*-- 16.02.2009 12:46:41--------------------------------------------------- 85 86 -----------------------------------------------------------------------*/ 87 SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap* pSource ) : 88 m_pImpl( new SfxItemPropertyMap_Impl( pSource->m_pImpl ) ) 89 { 90 } 91 /*-- 16.02.2009 10:03:51--------------------------------------------------- 92 93 -----------------------------------------------------------------------*/ 94 SfxItemPropertyMap::~SfxItemPropertyMap() 95 { 96 delete m_pImpl; 97 } 98 /*-- 16.02.2009 10:03:51--------------------------------------------------- 99 100 -----------------------------------------------------------------------*/ 101 const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const ::rtl::OUString &rName ) const 102 { 103 SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); 104 if( aIter == m_pImpl->end() ) 105 return 0; 106 return &aIter->second; 107 } 108 109 /*-- 16.02.2009 10:44:24--------------------------------------------------- 110 111 -----------------------------------------------------------------------*/ 112 uno::Sequence<beans::Property> SfxItemPropertyMap::getProperties() const 113 { 114 if( !m_pImpl->m_aPropSeq.getLength() ) 115 { 116 m_pImpl->m_aPropSeq.realloc( m_pImpl->size() ); 117 beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray(); 118 sal_uInt32 n = 0; 119 SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin(); 120 while( aIt != m_pImpl->end() ) 121 //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap ) 122 { 123 const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second; 124 pPropArray[n].Name = (*aIt).first; 125 pPropArray[n].Handle = pEntry->nWID; 126 if(pEntry->pType) 127 pPropArray[n].Type = *pEntry->pType; 128 pPropArray[n].Attributes = 129 sal::static_int_cast< sal_Int16 >(pEntry->nFlags); 130 n++; 131 ++aIt; 132 } 133 } 134 135 return m_pImpl->m_aPropSeq; 136 } 137 /*-- 16.02.2009 11:04:31--------------------------------------------------- 138 139 -----------------------------------------------------------------------*/ 140 beans::Property SfxItemPropertyMap::getPropertyByName( const ::rtl::OUString rName ) const 141 throw( beans::UnknownPropertyException ) 142 { 143 SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); 144 if( aIter == m_pImpl->end() ) 145 throw UnknownPropertyException(); 146 const SfxItemPropertySimpleEntry* pEntry = &aIter->second; 147 beans::Property aProp; 148 aProp.Name = rName; 149 aProp.Handle = pEntry->nWID; 150 if(pEntry->pType) 151 aProp.Type = *pEntry->pType; 152 aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags); 153 return aProp; 154 } 155 /*-- 16.02.2009 11:09:16--------------------------------------------------- 156 157 -----------------------------------------------------------------------*/ 158 sal_Bool SfxItemPropertyMap::hasPropertyByName( const ::rtl::OUString& rName ) const 159 { 160 SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); 161 return aIter != m_pImpl->end(); 162 } 163 /*-- 16.02.2009 11:25:14--------------------------------------------------- 164 165 -----------------------------------------------------------------------*/ 166 void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq ) 167 { 168 const beans::Property* pPropArray = rPropSeq.getConstArray(); 169 sal_uInt32 nElements = rPropSeq.getLength(); 170 for( sal_uInt32 nElement = 0; nElement < nElements; ++nElement ) 171 { 172 SfxItemPropertySimpleEntry aTemp( 173 sal::static_int_cast< sal_Int16 >( pPropArray[nElement].Handle ), //nWID 174 &pPropArray[nElement].Type, //pType 175 pPropArray[nElement].Attributes, //nFlags 176 0 ); //nMemberId 177 (*m_pImpl)[pPropArray[nElement].Name] = aTemp; 178 } 179 } 180 /*-- 18.02.2009 12:04:42--------------------------------------------------- 181 182 -----------------------------------------------------------------------*/ 183 PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const 184 { 185 PropertyEntryVector_t aRet; 186 aRet.reserve(m_pImpl->size()); 187 188 SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin(); 189 while( aIt != m_pImpl->end() ) 190 { 191 const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second; 192 aRet.push_back( SfxItemPropertyNamedEntry( (*aIt).first, * pEntry ) ); 193 ++aIt; 194 } 195 return aRet; 196 } 197 /*-- 18.02.2009 15:11:06--------------------------------------------------- 198 199 -----------------------------------------------------------------------*/ 200 sal_uInt32 SfxItemPropertyMap::getSize() const 201 { 202 return m_pImpl->size(); 203 } 204 /*-- 16.02.2009 13:44:54--------------------------------------------------- 205 206 -----------------------------------------------------------------------*/ 207 SfxItemPropertySet::~SfxItemPropertySet() 208 { 209 } 210 /* -----------------------------21.02.00 11:26-------------------------------- 211 212 ---------------------------------------------------------------------------*/ 213 sal_Bool SfxItemPropertySet::FillItem(SfxItemSet&, sal_uInt16, sal_Bool) const 214 { 215 return sal_False; 216 } 217 /* -----------------------------06.06.01 12:32-------------------------------- 218 219 ---------------------------------------------------------------------------*/ 220 void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry, 221 const SfxItemSet& rSet, Any& rAny ) const 222 throw(RuntimeException) 223 { 224 // get the SfxPoolItem 225 const SfxPoolItem* pItem = 0; 226 SfxItemState eState = rSet.GetItemState( rEntry.nWID, sal_True, &pItem ); 227 if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID ) 228 pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID); 229 // return item values as uno::Any 230 if(eState >= SFX_ITEM_DEFAULT && pItem) 231 { 232 pItem->QueryValue( rAny, rEntry.nMemberId ); 233 } 234 else 235 { 236 SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID); 237 if(FillItem(aSet, rEntry.nWID, sal_True)) 238 { 239 const SfxPoolItem& rItem = aSet.Get(rEntry.nWID); 240 rItem.QueryValue( rAny, rEntry.nMemberId ); 241 } 242 else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID)) 243 throw RuntimeException(); 244 } 245 246 247 // convert general SfxEnumItem values to specific values 248 if( rEntry.pType && TypeClass_ENUM == rEntry.pType->getTypeClass() && 249 rAny.getValueTypeClass() == TypeClass_LONG ) 250 { 251 sal_Int32 nTmp = *(sal_Int32*)rAny.getValue(); 252 rAny.setValue( &nTmp, *rEntry.pType ); 253 } 254 } 255 /* -----------------------------06.06.01 12:32-------------------------------- 256 257 ---------------------------------------------------------------------------*/ 258 void SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName, 259 const SfxItemSet& rSet, Any& rAny ) const 260 throw(RuntimeException, UnknownPropertyException) 261 { 262 // detect which-id 263 const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); 264 if ( !pEntry ) 265 throw UnknownPropertyException(); 266 getPropertyValue( *pEntry,rSet, rAny ); 267 } 268 /* -----------------------------21.02.00 11:26-------------------------------- 269 270 ---------------------------------------------------------------------------*/ 271 Any SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName, 272 const SfxItemSet& rSet ) const 273 throw(RuntimeException, UnknownPropertyException) 274 { 275 Any aVal; 276 getPropertyValue( rName,rSet, aVal ); 277 return aVal; 278 } 279 /* -----------------------------15.11.00 14:46-------------------------------- 280 281 ---------------------------------------------------------------------------*/ 282 void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry, 283 const Any& aVal, 284 SfxItemSet& rSet ) const 285 throw(RuntimeException, 286 IllegalArgumentException) 287 { 288 // get the SfxPoolItem 289 const SfxPoolItem* pItem = 0; 290 SfxPoolItem *pNewItem = 0; 291 SfxItemState eState = rSet.GetItemState( rEntry.nWID, sal_True, &pItem ); 292 if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID ) 293 pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID); 294 //maybe there's another way to find an Item 295 if(eState < SFX_ITEM_DEFAULT) 296 { 297 SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID); 298 if(FillItem(aSet, rEntry.nWID, sal_False)) 299 { 300 const SfxPoolItem &rItem = aSet.Get(rEntry.nWID); 301 pNewItem = rItem.Clone(); 302 } 303 } 304 if(!pNewItem && pItem) 305 { 306 pNewItem = pItem->Clone(); 307 } 308 if(pNewItem) 309 { 310 if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) ) 311 { 312 DELETEZ(pNewItem); 313 throw IllegalArgumentException(); 314 } 315 // apply new item 316 rSet.Put( *pNewItem, rEntry.nWID ); 317 delete pNewItem; 318 } 319 } 320 /* -----------------------------21.02.00 11:26-------------------------------- 321 322 ---------------------------------------------------------------------------*/ 323 void SfxItemPropertySet::setPropertyValue( const rtl::OUString &rName, 324 const Any& aVal, 325 SfxItemSet& rSet ) const 326 throw(RuntimeException, 327 IllegalArgumentException, 328 UnknownPropertyException) 329 { 330 const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); 331 if ( !pEntry ) 332 { 333 throw UnknownPropertyException(); 334 } 335 setPropertyValue(*pEntry, aVal, rSet); 336 } 337 /* -----------------------------21.02.00 11:26-------------------------------- 338 339 ---------------------------------------------------------------------------*/ 340 PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const 341 throw() 342 { 343 PropertyState eRet = PropertyState_DIRECT_VALUE; 344 sal_uInt16 nWhich = rEntry.nWID; 345 346 // item state holen 347 SfxItemState eState = rSet.GetItemState( nWhich, sal_False ); 348 // item-Wert als UnoAny zurueckgeben 349 if(eState == SFX_ITEM_DEFAULT) 350 eRet = PropertyState_DEFAULT_VALUE; 351 else if(eState < SFX_ITEM_DEFAULT) 352 eRet = PropertyState_AMBIGUOUS_VALUE; 353 return eRet; 354 } 355 PropertyState SfxItemPropertySet::getPropertyState( 356 const rtl::OUString& rName, const SfxItemSet& rSet) const 357 throw(UnknownPropertyException) 358 { 359 PropertyState eRet = PropertyState_DIRECT_VALUE; 360 361 // which-id ermitteln 362 const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); 363 if( !pEntry || !pEntry->nWID ) 364 { 365 throw UnknownPropertyException(); 366 } 367 sal_uInt16 nWhich = pEntry->nWID; 368 369 // item holen 370 const SfxPoolItem* pItem = 0; 371 SfxItemState eState = rSet.GetItemState( nWhich, sal_False, &pItem ); 372 if(!pItem && nWhich != rSet.GetPool()->GetSlotId(nWhich)) 373 pItem = &rSet.GetPool()->GetDefaultItem(nWhich); 374 // item-Wert als UnoAny zurueckgeben 375 if(eState == SFX_ITEM_DEFAULT) 376 eRet = PropertyState_DEFAULT_VALUE; 377 else if(eState < SFX_ITEM_DEFAULT) 378 eRet = PropertyState_AMBIGUOUS_VALUE; 379 return eRet; 380 } 381 /* -----------------------------21.02.00 11:26-------------------------------- 382 383 ---------------------------------------------------------------------------*/ 384 Reference<XPropertySetInfo> 385 SfxItemPropertySet::getPropertySetInfo() const 386 { 387 if( !m_xInfo.is() ) 388 m_xInfo = new SfxItemPropertySetInfo( &m_aMap ); 389 return m_xInfo; 390 } 391 /*-- 16.02.2009 13:49:25--------------------------------------------------- 392 393 -----------------------------------------------------------------------*/ 394 struct SfxItemPropertySetInfo_Impl 395 { 396 SfxItemPropertyMap* m_pOwnMap; 397 }; 398 /*-- 16.02.2009 13:49:24--------------------------------------------------- 399 400 -----------------------------------------------------------------------*/ 401 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap *pMap ) : 402 m_pImpl( new SfxItemPropertySetInfo_Impl ) 403 { 404 m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pMap ); 405 } 406 /*-- 16.02.2009 13:49:25--------------------------------------------------- 407 408 -----------------------------------------------------------------------*/ 409 SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries ) : 410 m_pImpl( new SfxItemPropertySetInfo_Impl ) 411 { 412 m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pEntries ); 413 } 414 /* -----------------------------21.02.00 11:09-------------------------------- 415 416 ---------------------------------------------------------------------------*/ 417 Sequence< Property > SAL_CALL 418 SfxItemPropertySetInfo::getProperties( ) 419 throw(RuntimeException) 420 { 421 return m_pImpl->m_pOwnMap->getProperties(); 422 } 423 /*-- 16.02.2009 13:49:27--------------------------------------------------- 424 425 -----------------------------------------------------------------------*/ 426 const SfxItemPropertyMap* SfxItemPropertySetInfo::getMap() const 427 { 428 return m_pImpl->m_pOwnMap; 429 } 430 431 /*-- 16.02.2009 12:43:36--------------------------------------------------- 432 433 -----------------------------------------------------------------------*/ 434 SfxItemPropertySetInfo::~SfxItemPropertySetInfo() 435 { 436 delete m_pImpl->m_pOwnMap; 437 delete m_pImpl; 438 } 439 /* -----------------------------21.02.00 11:27-------------------------------- 440 441 ---------------------------------------------------------------------------*/ 442 Property SAL_CALL 443 SfxItemPropertySetInfo::getPropertyByName( const ::rtl::OUString& rName ) 444 throw(UnknownPropertyException, RuntimeException) 445 { 446 return m_pImpl->m_pOwnMap->getPropertyByName( rName ); 447 } 448 /* -----------------------------21.02.00 11:28-------------------------------- 449 450 ---------------------------------------------------------------------------*/ 451 sal_Bool SAL_CALL 452 SfxItemPropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName ) 453 throw(RuntimeException) 454 { 455 return m_pImpl->m_pOwnMap->hasPropertyByName( rName ); 456 } 457 /* -----------------------------21.02.00 12:03-------------------------------- 458 459 ---------------------------------------------------------------------------*/ 460 SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( 461 const SfxItemPropertyMapEntry *pMap, 462 const Sequence<Property>& rPropSeq ) : 463 aExtMap( pMap ) 464 { 465 aExtMap.mergeProperties( rPropSeq ); 466 } 467 /*-- 16.02.2009 12:06:49--------------------------------------------------- 468 469 -----------------------------------------------------------------------*/ 470 SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo() 471 { 472 } 473 /* -----------------------------21.02.00 12:03-------------------------------- 474 475 ---------------------------------------------------------------------------*/ 476 Sequence< Property > SAL_CALL 477 SfxExtItemPropertySetInfo::getProperties( ) throw(RuntimeException) 478 { 479 return aExtMap.getProperties(); 480 } 481 /* -----------------------------21.02.00 12:03-------------------------------- 482 483 ---------------------------------------------------------------------------*/ 484 Property SAL_CALL 485 SfxExtItemPropertySetInfo::getPropertyByName( const rtl::OUString& rPropertyName ) 486 throw(UnknownPropertyException, RuntimeException) 487 { 488 return aExtMap.getPropertyByName( rPropertyName ); 489 } 490 /* -----------------------------21.02.00 12:03-------------------------------- 491 492 ---------------------------------------------------------------------------*/ 493 sal_Bool SAL_CALL 494 SfxExtItemPropertySetInfo::hasPropertyByName( const rtl::OUString& rPropertyName ) 495 throw(RuntimeException) 496 { 497 return aExtMap.hasPropertyByName( rPropertyName ); 498 } 499 500