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