/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include #include #include #include /************************************************************************* UNO III Implementation *************************************************************************/ using namespace com::sun::star; using namespace com::sun::star::beans; using namespace com::sun::star::lang; using namespace com::sun::star::uno; struct equalOUString { bool operator()(const ::rtl::OUString& r1, const ::rtl::OUString& r2) const { return r1.equals( r2 ); } }; typedef ::boost::unordered_map< ::rtl::OUString, SfxItemPropertySimpleEntry, ::rtl::OUStringHash, equalOUString > SfxItemPropertyHashMap_t; class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t { public: mutable uno::Sequence< beans::Property > m_aPropSeq; SfxItemPropertyMap_Impl(){} SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource ); }; SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource ) { this->SfxItemPropertyHashMap_t::operator=( *pSource ); m_aPropSeq = pSource->m_aPropSeq; } SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) : m_pImpl( new SfxItemPropertyMap_Impl ) { while( pEntries->pName ) { ::rtl::OUString sEntry(pEntries->pName, pEntries->nNameLen, RTL_TEXTENCODING_ASCII_US ); (*m_pImpl) [ sEntry ] = pEntries; ++pEntries; } } SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap& rSource ) : m_pImpl( new SfxItemPropertyMap_Impl( rSource.m_pImpl ) ) { } SfxItemPropertyMap::~SfxItemPropertyMap() { delete m_pImpl; } const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const ::rtl::OUString &rName ) const { SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); if( aIter == m_pImpl->end() ) return 0; return &aIter->second; } uno::Sequence SfxItemPropertyMap::getProperties() const { if( !m_pImpl->m_aPropSeq.getLength() ) { m_pImpl->m_aPropSeq.realloc( m_pImpl->size() ); beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray(); sal_uInt32 n = 0; SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin(); while( aIt != m_pImpl->end() ) //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap ) { const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second; pPropArray[n].Name = (*aIt).first; pPropArray[n].Handle = pEntry->nWID; if(pEntry->pType) pPropArray[n].Type = *pEntry->pType; pPropArray[n].Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags); n++; ++aIt; } } return m_pImpl->m_aPropSeq; } beans::Property SfxItemPropertyMap::getPropertyByName( const ::rtl::OUString rName ) const throw( beans::UnknownPropertyException ) { SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); if( aIter == m_pImpl->end() ) throw UnknownPropertyException(); const SfxItemPropertySimpleEntry* pEntry = &aIter->second; beans::Property aProp; aProp.Name = rName; aProp.Handle = pEntry->nWID; if(pEntry->pType) aProp.Type = *pEntry->pType; aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags); return aProp; } sal_Bool SfxItemPropertyMap::hasPropertyByName( const ::rtl::OUString& rName ) const { SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName); return aIter != m_pImpl->end(); } void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq ) { const beans::Property* pPropArray = rPropSeq.getConstArray(); sal_uInt32 nElements = rPropSeq.getLength(); for( sal_uInt32 nElement = 0; nElement < nElements; ++nElement ) { SfxItemPropertySimpleEntry aTemp( sal::static_int_cast< sal_Int16 >( pPropArray[nElement].Handle ), //nWID &pPropArray[nElement].Type, //pType pPropArray[nElement].Attributes, //nFlags 0 ); //nMemberId (*m_pImpl)[pPropArray[nElement].Name] = aTemp; } } PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const { PropertyEntryVector_t aRet; aRet.reserve(m_pImpl->size()); SfxItemPropertyHashMap_t::const_iterator aIt = m_pImpl->begin(); while( aIt != m_pImpl->end() ) { const SfxItemPropertySimpleEntry* pEntry = &(*aIt).second; aRet.push_back( SfxItemPropertyNamedEntry( (*aIt).first, * pEntry ) ); ++aIt; } return aRet; } sal_uInt32 SfxItemPropertyMap::getSize() const { return m_pImpl->size(); } SfxItemPropertySet::~SfxItemPropertySet() { } sal_Bool SfxItemPropertySet::FillItem(SfxItemSet&, sal_uInt16, sal_Bool) const { return sal_False; } void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet, Any& rAny ) const throw(RuntimeException) { // get the SfxPoolItem const SfxPoolItem* pItem = 0; SfxItemState eState = rSet.GetItemState( rEntry.nWID, sal_True, &pItem ); if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID ) pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID); // return item values as uno::Any if(eState >= SFX_ITEM_DEFAULT && pItem) { pItem->QueryValue( rAny, rEntry.nMemberId ); } else { SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID); if(FillItem(aSet, rEntry.nWID, sal_True)) { const SfxPoolItem& rItem = aSet.Get(rEntry.nWID); rItem.QueryValue( rAny, rEntry.nMemberId ); } else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID)) throw RuntimeException(); } // convert general SfxEnumItem values to specific values if( rEntry.pType && TypeClass_ENUM == rEntry.pType->getTypeClass() && rAny.getValueTypeClass() == TypeClass_LONG ) { sal_Int32 nTmp = *(sal_Int32*)rAny.getValue(); rAny.setValue( &nTmp, *rEntry.pType ); } } void SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName, const SfxItemSet& rSet, Any& rAny ) const throw(RuntimeException, UnknownPropertyException) { // detect which-id const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); if ( !pEntry ) throw UnknownPropertyException(); getPropertyValue( *pEntry,rSet, rAny ); } Any SfxItemPropertySet::getPropertyValue( const rtl::OUString &rName, const SfxItemSet& rSet ) const throw(RuntimeException, UnknownPropertyException) { Any aVal; getPropertyValue( rName,rSet, aVal ); return aVal; } void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry, const Any& aVal, SfxItemSet& rSet ) const throw(RuntimeException, IllegalArgumentException) { // get the SfxPoolItem const SfxPoolItem* pItem = 0; SfxPoolItem *pNewItem = 0; SfxItemState eState = rSet.GetItemState( rEntry.nWID, sal_True, &pItem ); if(SFX_ITEM_SET != eState && SFX_WHICH_MAX > rEntry.nWID ) pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID); //maybe there's another way to find an Item if(eState < SFX_ITEM_DEFAULT) { SfxItemSet aSet(*rSet.GetPool(), rEntry.nWID, rEntry.nWID); if(FillItem(aSet, rEntry.nWID, sal_False)) { const SfxPoolItem &rItem = aSet.Get(rEntry.nWID); pNewItem = rItem.Clone(); } } if(!pNewItem && pItem) { pNewItem = pItem->Clone(); } if(pNewItem) { if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) ) { DELETEZ(pNewItem); throw IllegalArgumentException(); } // apply new item rSet.Put( *pNewItem, rEntry.nWID ); delete pNewItem; } } void SfxItemPropertySet::setPropertyValue( const rtl::OUString &rName, const Any& aVal, SfxItemSet& rSet ) const throw(RuntimeException, IllegalArgumentException, UnknownPropertyException) { const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); if ( !pEntry ) { throw UnknownPropertyException(); } setPropertyValue(*pEntry, aVal, rSet); } PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const throw() { PropertyState eRet = PropertyState_DIRECT_VALUE; sal_uInt16 nWhich = rEntry.nWID; // item state holen SfxItemState eState = rSet.GetItemState( nWhich, sal_False ); // item-Wert als UnoAny zurueckgeben if(eState == SFX_ITEM_DEFAULT) eRet = PropertyState_DEFAULT_VALUE; else if(eState < SFX_ITEM_DEFAULT) eRet = PropertyState_AMBIGUOUS_VALUE; return eRet; } PropertyState SfxItemPropertySet::getPropertyState( const rtl::OUString& rName, const SfxItemSet& rSet) const throw(UnknownPropertyException) { PropertyState eRet = PropertyState_DIRECT_VALUE; // which-id ermitteln const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName ); if( !pEntry || !pEntry->nWID ) { throw UnknownPropertyException(); } sal_uInt16 nWhich = pEntry->nWID; // item holen const SfxPoolItem* pItem = 0; SfxItemState eState = rSet.GetItemState( nWhich, sal_False, &pItem ); if(!pItem && nWhich != rSet.GetPool()->GetSlotId(nWhich)) pItem = &rSet.GetPool()->GetDefaultItem(nWhich); // item-Wert als UnoAny zurueckgeben if(eState == SFX_ITEM_DEFAULT) eRet = PropertyState_DEFAULT_VALUE; else if(eState < SFX_ITEM_DEFAULT) eRet = PropertyState_AMBIGUOUS_VALUE; return eRet; } Reference SfxItemPropertySet::getPropertySetInfo() const { if( !m_xInfo.is() ) m_xInfo = new SfxItemPropertySetInfo( m_aMap ); return m_xInfo; } struct SfxItemPropertySetInfo_Impl { SfxItemPropertyMap* m_pOwnMap; }; SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap &rMap ) : m_pImpl( new SfxItemPropertySetInfo_Impl ) { m_pImpl->m_pOwnMap = new SfxItemPropertyMap( rMap ); } SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries ) : m_pImpl( new SfxItemPropertySetInfo_Impl ) { m_pImpl->m_pOwnMap = new SfxItemPropertyMap( pEntries ); } Sequence< Property > SAL_CALL SfxItemPropertySetInfo::getProperties( ) throw(RuntimeException) { return m_pImpl->m_pOwnMap->getProperties(); } SfxItemPropertySetInfo::~SfxItemPropertySetInfo() { delete m_pImpl->m_pOwnMap; delete m_pImpl; } Property SAL_CALL SfxItemPropertySetInfo::getPropertyByName( const ::rtl::OUString& rName ) throw(UnknownPropertyException, RuntimeException) { return m_pImpl->m_pOwnMap->getPropertyByName( rName ); } sal_Bool SAL_CALL SfxItemPropertySetInfo::hasPropertyByName( const ::rtl::OUString& rName ) throw(RuntimeException) { return m_pImpl->m_pOwnMap->hasPropertyByName( rName ); } SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( const SfxItemPropertyMapEntry *pMap, const Sequence& rPropSeq ) : aExtMap( pMap ) { aExtMap.mergeProperties( rPropSeq ); } SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo() { } Sequence< Property > SAL_CALL SfxExtItemPropertySetInfo::getProperties( ) throw(RuntimeException) { return aExtMap.getProperties(); } Property SAL_CALL SfxExtItemPropertySetInfo::getPropertyByName( const rtl::OUString& rPropertyName ) throw(UnknownPropertyException, RuntimeException) { return aExtMap.getPropertyByName( rPropertyName ); } sal_Bool SAL_CALL SfxExtItemPropertySetInfo::hasPropertyByName( const rtl::OUString& rPropertyName ) throw(RuntimeException) { return aExtMap.hasPropertyByName( rPropertyName ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */