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_svx.hxx" 30 31 #include <set> 32 #include <svl/itempool.hxx> 33 #include <svl/itemset.hxx> 34 #include <svl/style.hxx> 35 #include <comphelper/stl_types.hxx> 36 37 #include <svx/svdmodel.hxx> 38 #include "UnoNameItemTable.hxx" 39 #include <vos/mutex.hxx> 40 #include <vcl/svapp.hxx> 41 42 #include "svx/unoapi.hxx" 43 44 using namespace ::com::sun::star; 45 using namespace ::rtl; 46 using namespace ::cppu; 47 using namespace ::vos; 48 49 SvxUnoNameItemTable::SvxUnoNameItemTable( SdrModel* pModel, sal_uInt16 nWhich, sal_uInt8 nMemberId ) throw() 50 : mpModel( pModel ), 51 mpModelPool( pModel ? &pModel->GetItemPool() : NULL ), 52 mnWhich( nWhich ), mnMemberId( nMemberId ) 53 { 54 if( pModel ) 55 StartListening( *pModel ); 56 } 57 58 SvxUnoNameItemTable::~SvxUnoNameItemTable() throw() 59 { 60 if( mpModel ) 61 EndListening( *mpModel ); 62 dispose(); 63 } 64 65 bool SvxUnoNameItemTable::isValid( const NameOrIndex* pItem ) const 66 { 67 return pItem && (pItem->GetName().Len() != 0); 68 } 69 70 void SvxUnoNameItemTable::dispose() 71 { 72 ItemPoolVector::iterator aIter = maItemSetVector.begin(); 73 const ItemPoolVector::iterator aEnd = maItemSetVector.end(); 74 75 while( aIter != aEnd ) 76 { 77 delete (*aIter++); 78 } 79 80 maItemSetVector.clear(); 81 } 82 83 void SvxUnoNameItemTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw() 84 { 85 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint ); 86 87 if( pSdrHint && HINT_MODELCLEARED == pSdrHint->GetKind() ) 88 dispose(); 89 } 90 91 sal_Bool SAL_CALL SvxUnoNameItemTable::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException) 92 { 93 uno::Sequence< OUString > aSNL( getSupportedServiceNames() ); 94 const OUString * pArray = aSNL.getConstArray(); 95 96 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ ) 97 if( pArray[i] == ServiceName ) 98 return sal_True; 99 100 return sal_False; 101 } 102 103 void SAL_CALL SvxUnoNameItemTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement ) 104 { 105 SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, mnWhich, mnWhich ); 106 maItemSetVector.push_back( mpInSet ); 107 108 NameOrIndex* pNewItem = createItem(); 109 pNewItem->SetName( String( aName ) ); 110 pNewItem->PutValue( aElement, mnMemberId ); 111 mpInSet->Put( *pNewItem, mnWhich ); 112 delete pNewItem; 113 } 114 115 // XNameContainer 116 void SAL_CALL SvxUnoNameItemTable::insertByName( const OUString& aApiName, const uno::Any& aElement ) 117 throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException ) 118 { 119 OGuard aGuard( Application::GetSolarMutex() ); 120 121 if( hasByName( aApiName ) ) 122 throw container::ElementExistException(); 123 124 String aName; 125 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName ); 126 127 ImplInsertByName( aName, aElement ); 128 } 129 130 131 132 void SAL_CALL SvxUnoNameItemTable::removeByName( const OUString& aApiName ) 133 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 134 { 135 OGuard aGuard( Application::GetSolarMutex() ); 136 137 // a little quickfix for 2.0 to let applications clear api 138 // created items that are not used 139 if( aApiName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("~clear~") ) ) 140 { 141 dispose(); 142 return; 143 } 144 145 String Name; 146 SvxUnogetInternalNameForItem( mnWhich, aApiName, Name ); 147 148 ItemPoolVector::iterator aIter = maItemSetVector.begin(); 149 const ItemPoolVector::iterator aEnd = maItemSetVector.end(); 150 151 NameOrIndex *pItem; 152 const String aSearchName( Name ); 153 154 while( aIter != aEnd ) 155 { 156 pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) ); 157 if( pItem->GetName() == aSearchName ) 158 { 159 delete (*aIter); 160 maItemSetVector.erase( aIter ); 161 return; 162 } 163 aIter++; 164 } 165 166 if( !hasByName( Name ) ) 167 throw container::NoSuchElementException(); 168 } 169 170 // XNameReplace 171 void SAL_CALL SvxUnoNameItemTable::replaceByName( const OUString& aApiName, const uno::Any& aElement ) 172 throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ) 173 { 174 OGuard aGuard( Application::GetSolarMutex() ); 175 176 String aName; 177 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName ); 178 179 ItemPoolVector::iterator aIter = maItemSetVector.begin(); 180 const ItemPoolVector::iterator aEnd = maItemSetVector.end(); 181 182 NameOrIndex *pItem; 183 const String aSearchName( aName ); 184 185 while( aIter != aEnd ) 186 { 187 pItem = (NameOrIndex *)&((*aIter)->Get( mnWhich ) ); 188 if( pItem->GetName() == aSearchName ) 189 { 190 NameOrIndex* pNewItem = createItem(); 191 pNewItem->SetName( aSearchName ); 192 if( !pNewItem->PutValue( aElement, mnMemberId ) || !isValid( pNewItem ) ) 193 throw lang::IllegalArgumentException(); 194 195 (*aIter)->Put( *pNewItem ); 196 return; 197 } 198 aIter++; 199 } 200 201 // if it is not in our own sets, modify the pool! 202 sal_Bool bFound = sal_False; 203 204 sal_uInt32 nSurrogate; 205 sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0; 206 for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ ) 207 { 208 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate); 209 if( pItem && pItem->GetName() == aSearchName ) 210 { 211 pItem->PutValue( aElement, mnMemberId ); 212 bFound = sal_True; 213 break; 214 } 215 } 216 217 if( bFound ) 218 ImplInsertByName( aName, aElement ); 219 else 220 throw container::NoSuchElementException(); 221 222 if( !hasByName( aName ) ) 223 throw container::NoSuchElementException(); 224 } 225 226 // XNameAccess 227 uno::Any SAL_CALL SvxUnoNameItemTable::getByName( const OUString& aApiName ) 228 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) 229 { 230 OGuard aGuard( Application::GetSolarMutex() ); 231 232 String aName; 233 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName ); 234 235 uno::Any aAny; 236 237 if( mpModelPool && aName.Len() != 0 ) 238 { 239 const String aSearchName( aName ); 240 NameOrIndex *pItem; 241 sal_uInt32 nSurrogate; 242 243 sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0; 244 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ ) 245 { 246 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate ); 247 248 if( isValid( pItem ) && (pItem->GetName() == aSearchName) ) 249 { 250 pItem->QueryValue( aAny, mnMemberId ); 251 return aAny; 252 } 253 } 254 } 255 256 throw container::NoSuchElementException(); 257 } 258 259 uno::Sequence< OUString > SAL_CALL SvxUnoNameItemTable::getElementNames( ) 260 throw( uno::RuntimeException ) 261 { 262 OGuard aGuard( Application::GetSolarMutex() ); 263 264 std::set< OUString, comphelper::UStringLess > aNameSet; 265 266 NameOrIndex *pItem; 267 OUString aApiName; 268 269 const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0; 270 sal_uInt32 nSurrogate; 271 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ ) 272 { 273 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate ); 274 275 if( !isValid( pItem ) ) 276 continue; 277 278 SvxUnogetApiNameForItem( mnWhich, pItem->GetName(), aApiName ); 279 aNameSet.insert( aApiName ); 280 } 281 282 uno::Sequence< OUString > aSeq( aNameSet.size() ); 283 OUString* pNames = aSeq.getArray(); 284 285 std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() ); 286 const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() ); 287 288 while( aIter != aEnd ) 289 { 290 *pNames++ = *aIter++; 291 } 292 293 return aSeq; 294 } 295 296 sal_Bool SAL_CALL SvxUnoNameItemTable::hasByName( const OUString& aApiName ) 297 throw( uno::RuntimeException ) 298 { 299 OGuard aGuard( Application::GetSolarMutex() ); 300 301 String aName; 302 SvxUnogetInternalNameForItem( mnWhich, aApiName, aName ); 303 304 if( aName.Len() == 0 ) 305 return sal_False; 306 307 const String aSearchName( aName ); 308 sal_uInt32 nSurrogate; 309 310 const NameOrIndex *pItem; 311 312 sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0; 313 for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ ) 314 { 315 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate ); 316 if( isValid( pItem ) && (pItem->GetName() == aSearchName) ) 317 return sal_True; 318 } 319 320 return sal_False; 321 } 322 323 sal_Bool SAL_CALL SvxUnoNameItemTable::hasElements( ) 324 throw( uno::RuntimeException ) 325 { 326 OGuard aGuard( Application::GetSolarMutex() ); 327 328 const NameOrIndex *pItem; 329 330 sal_uInt32 nSurrogate; 331 const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0; 332 for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ ) 333 { 334 pItem = (NameOrIndex*)mpModelPool->GetItem2( mnWhich, nSurrogate ); 335 336 if( isValid( pItem ) ) 337 return sal_True; 338 } 339 340 return sal_False; 341 } 342