update credits
[LibreOffice.git] / svx / source / unodraw / unomtabl.cxx
blob81b61e729a10773a0d7d030c5a6c6149e0b02b92
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <set>
22 #include <comphelper/stl_types.hxx>
23 #include <com/sun/star/lang/XServiceInfo.hpp>
24 #include <com/sun/star/container/XNameContainer.hpp>
25 #include <com/sun/star/drawing/PointSequence.hpp>
26 #include <svl/style.hxx>
28 #include <cppuhelper/implbase2.hxx>
29 #include <svl/itempool.hxx>
30 #include <svl/itemset.hxx>
31 #include <svl/lstner.hxx>
32 #include <svx/xlnedit.hxx>
33 #include <svx/xlnstit.hxx>
34 #include <svx/svdmodel.hxx>
35 #include <svx/xdef.hxx>
36 #include <svx/xflhtit.hxx>
38 #include <vector>
39 #include <osl/mutex.hxx>
40 #include <vcl/svapp.hxx>
43 #include "svx/unofill.hxx"
45 #include "svx/unoapi.hxx"
47 using namespace ::com::sun::star;
48 using namespace ::rtl;
49 using namespace ::cppu;
51 typedef std::vector< SfxItemSet* > ItemPoolVector;
53 class SvxUnoMarkerTable : public WeakImplHelper2< container::XNameContainer, lang::XServiceInfo >,
54 public SfxListener
56 private:
57 SdrModel* mpModel;
58 SfxItemPool* mpModelPool;
60 ItemPoolVector maItemSetVector;
62 public:
63 SvxUnoMarkerTable( SdrModel* pModel ) throw();
64 virtual ~SvxUnoMarkerTable() throw();
66 void dispose();
68 // SfxListener
69 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw ();
71 void SAL_CALL ImplInsertByName( const OUString& aName, const uno::Any& aElement );
73 // XServiceInfo
74 virtual OUString SAL_CALL getImplementationName( ) throw( uno::RuntimeException );
75 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw( uno::RuntimeException);
76 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw( uno::RuntimeException);
78 // XNameContainer
79 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException);
80 virtual void SAL_CALL removeByName( const OUString& Name ) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
82 // XNameReplace
83 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
85 // XNameAccess
86 virtual uno::Any SAL_CALL getByName( const OUString& aName ) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
87 virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) throw( uno::RuntimeException);
88 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw( uno::RuntimeException);
90 // XElementAccess
91 virtual uno::Type SAL_CALL getElementType( ) throw( uno::RuntimeException);
92 virtual sal_Bool SAL_CALL hasElements( ) throw( uno::RuntimeException);
95 SvxUnoMarkerTable::SvxUnoMarkerTable( SdrModel* pModel ) throw()
96 : mpModel( pModel ),
97 mpModelPool( pModel ? &pModel->GetItemPool() : (SfxItemPool*)NULL )
99 if( pModel )
100 StartListening( *pModel );
103 SvxUnoMarkerTable::~SvxUnoMarkerTable() throw()
105 if( mpModel )
106 EndListening( *mpModel );
107 dispose();
110 void SvxUnoMarkerTable::dispose()
112 ItemPoolVector::iterator aIter = maItemSetVector.begin();
113 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
115 while( aIter != aEnd )
117 delete (*aIter++);
120 maItemSetVector.clear();
123 // SfxListener
124 void SvxUnoMarkerTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
126 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
128 if( pSdrHint && HINT_MODELCLEARED == pSdrHint->GetKind() )
129 dispose();
132 sal_Bool SAL_CALL SvxUnoMarkerTable::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
134 uno::Sequence< OUString > aSNL( getSupportedServiceNames() );
135 const OUString * pArray = aSNL.getConstArray();
137 for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
138 if( pArray[i] == ServiceName )
139 return sal_True;
141 return sal_False;
144 OUString SAL_CALL SvxUnoMarkerTable::getImplementationName() throw( uno::RuntimeException )
146 return OUString("SvxUnoMarkerTable");
149 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getSupportedServiceNames( )
150 throw( uno::RuntimeException )
152 uno::Sequence< OUString > aSNS( 1 );
153 aSNS.getArray()[0] = OUString("com.sun.star.drawing.MarkerTable" );
154 return aSNS;
157 void SAL_CALL SvxUnoMarkerTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
159 SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, XATTR_LINESTART, XATTR_LINEEND );
160 maItemSetVector.push_back( mpInSet );
162 XLineEndItem aEndMarker;
163 aEndMarker.SetName( String( aName ) );
164 aEndMarker.PutValue( aElement );
166 mpInSet->Put( aEndMarker, XATTR_LINEEND );
168 XLineStartItem aStartMarker;
169 aStartMarker.SetName( String( aName ) );
170 aStartMarker.PutValue( aElement );
172 mpInSet->Put( aStartMarker, XATTR_LINESTART );
175 // XNameContainer
176 void SAL_CALL SvxUnoMarkerTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
177 throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
179 SolarMutexGuard aGuard;
181 if( hasByName( aApiName ) )
182 throw container::ElementExistException();
184 OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
186 ImplInsertByName( aName, aElement );
189 void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName )
190 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
192 SolarMutexGuard aGuard;
194 // a little quickfix for 2.0 to let applications clear api
195 // created items that are not used
196 if ( aApiName == "~clear~" )
198 dispose();
199 return;
202 OUString Name = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
204 ItemPoolVector::iterator aIter = maItemSetVector.begin();
205 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
207 NameOrIndex *pItem;
208 const String aSearchName( Name );
210 while( aIter != aEnd )
212 pItem = (NameOrIndex *)&((*aIter)->Get( XATTR_LINEEND ) );
213 if( pItem->GetName() == aSearchName )
215 delete (*aIter);
216 maItemSetVector.erase( aIter );
217 return;
219 ++aIter;
222 if( !hasByName( Name ) )
223 throw container::NoSuchElementException();
226 // XNameReplace
227 void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
228 throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
230 SolarMutexGuard aGuard;
232 OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
234 ItemPoolVector::iterator aIter = maItemSetVector.begin();
235 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
237 NameOrIndex *pItem;
238 const String aSearchName( aName );
240 while( aIter != aEnd )
242 pItem = (NameOrIndex *)&((*aIter)->Get( XATTR_LINEEND ) );
243 if( pItem->GetName() == aSearchName )
245 XLineEndItem aEndMarker;
246 aEndMarker.SetName( aSearchName );
247 if( !aEndMarker.PutValue( aElement ) )
248 throw lang::IllegalArgumentException();
250 (*aIter)->Put( aEndMarker, XATTR_LINEEND );
252 XLineStartItem aStartMarker;
253 aStartMarker.SetName( aSearchName );
254 aStartMarker.PutValue( aElement );
256 (*aIter)->Put( aStartMarker, XATTR_LINESTART );
257 return;
259 ++aIter;
262 // if it is not in our own sets, modify the pool!
263 bool bFound = false;
265 sal_uInt32 nSurrogate;
266 const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
267 for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
269 pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
270 if( pItem && pItem->GetName() == aSearchName )
272 pItem->PutValue( aElement );
273 bFound = true;
274 break;
278 const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
279 for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
281 pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
282 if( pItem && pItem->GetName() == aSearchName )
284 pItem->PutValue( aElement );
285 bFound = true;
286 break;
290 if( bFound )
291 ImplInsertByName( aName, aElement );
292 else
293 throw container::NoSuchElementException();
296 static bool getByNameFromPool( const String& rSearchName, SfxItemPool* pPool, sal_uInt16 nWhich, uno::Any& rAny )
298 NameOrIndex *pItem;
299 const sal_uInt32 nSurrogateCount = pPool ? pPool->GetItemCount2( nWhich ) : 0;
300 for( sal_uInt32 nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
302 pItem = (NameOrIndex*)pPool->GetItem2( nWhich, nSurrogate );
304 if( pItem && pItem->GetName() == rSearchName )
306 pItem->QueryValue( rAny, 0 );
307 return true;
311 return false;
314 // XNameAccess
315 uno::Any SAL_CALL SvxUnoMarkerTable::getByName( const OUString& aApiName )
316 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
318 SolarMutexGuard aGuard;
320 OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
322 uno::Any aAny;
324 if (mpModelPool && !aName.isEmpty())
328 if (getByNameFromPool(aName, mpModelPool, XATTR_LINESTART, aAny))
329 break;
331 if (getByNameFromPool(aName, mpModelPool, XATTR_LINEEND, aAny))
332 break;
334 throw container::NoSuchElementException();
336 while(0);
339 return aAny;
342 static void createNamesForPool( SfxItemPool* pPool, sal_uInt16 nWhich, std::set< OUString, comphelper::UStringLess >& rNameSet )
344 const sal_uInt32 nSuroCount = pPool->GetItemCount2( nWhich );
346 for(sal_uInt32 nSurrogate = 0; nSurrogate < nSuroCount; ++nSurrogate)
348 NameOrIndex* pItem = (NameOrIndex*)pPool->GetItem2( nWhich, nSurrogate );
350 if( pItem == NULL || pItem->GetName().Len() == 0 )
351 continue;
353 OUString aName = SvxUnogetApiNameForItem(XATTR_LINEEND, pItem->GetName());
354 rNameSet.insert( aName );
358 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getElementNames()
359 throw( uno::RuntimeException )
361 SolarMutexGuard aGuard;
363 std::set< OUString, comphelper::UStringLess > aNameSet;
365 // search model pool for line starts
366 createNamesForPool( mpModelPool, XATTR_LINESTART, aNameSet );
368 // search model pool for line ends
369 createNamesForPool( mpModelPool, XATTR_LINEEND, aNameSet );
371 uno::Sequence< OUString > aSeq( aNameSet.size() );
372 OUString* pNames = aSeq.getArray();
374 std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() );
375 const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() );
377 while( aIter != aEnd )
379 *pNames++ = *aIter++;
382 return aSeq;
385 sal_Bool SAL_CALL SvxUnoMarkerTable::hasByName( const OUString& aName )
386 throw( uno::RuntimeException )
388 SolarMutexGuard aGuard;
390 if( aName.isEmpty() )
391 return sal_False;
393 String aSearchName;
395 NameOrIndex *pItem;
397 aSearchName = SvxUnogetInternalNameForItem(XATTR_LINESTART, aName);
398 sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
399 sal_uInt32 nSurrogate;
400 for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
402 pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
403 if( pItem && pItem->GetName() == aSearchName )
404 return sal_True;
407 aSearchName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aName);
408 sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
409 for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
411 pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
412 if( pItem && pItem->GetName() == aSearchName )
413 return sal_True;
416 return sal_False;
419 // XElementAccess
420 uno::Type SAL_CALL SvxUnoMarkerTable::getElementType( )
421 throw( uno::RuntimeException )
423 return ::getCppuType((const drawing::PointSequence*)0);
426 sal_Bool SAL_CALL SvxUnoMarkerTable::hasElements( )
427 throw( uno::RuntimeException )
429 SolarMutexGuard aGuard;
431 NameOrIndex *pItem;
433 const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
434 sal_uInt32 nSurrogate;
435 for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
437 pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
438 if( pItem && pItem->GetName().Len() != 0 )
439 return sal_True;
442 const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
443 for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
445 pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
446 if( pItem && pItem->GetName().Len() != 0 )
447 return sal_True;
450 return sal_False;
454 * Create a hatchtable
456 uno::Reference< uno::XInterface > SAL_CALL SvxUnoMarkerTable_createInstance( SdrModel* pModel )
458 return *new SvxUnoMarkerTable(pModel);
463 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */