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