bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / unodraw / unomtabl.cxx
bloba0d9e57d9450f93d851a43f33ddde5a6ac8230bc
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 <com/sun/star/lang/XServiceInfo.hpp>
23 #include <com/sun/star/container/XNameContainer.hpp>
24 #include <com/sun/star/drawing/PointSequence.hpp>
25 #include <svl/style.hxx>
27 #include <cppuhelper/implbase2.hxx>
28 #include <cppuhelper/supportsservice.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 ::cppu;
50 typedef std::vector< SfxItemSet* > ItemPoolVector;
52 class SvxUnoMarkerTable : public WeakImplHelper2< container::XNameContainer, lang::XServiceInfo >,
53 public SfxListener
55 private:
56 SdrModel* mpModel;
57 SfxItemPool* mpModelPool;
59 ItemPoolVector maItemSetVector;
61 public:
62 SvxUnoMarkerTable( SdrModel* pModel ) throw();
63 virtual ~SvxUnoMarkerTable() throw();
65 void dispose();
67 // SfxListener
68 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw () SAL_OVERRIDE;
70 void SAL_CALL ImplInsertByName( const OUString& aName, const uno::Any& aElement );
72 // XServiceInfo
73 virtual OUString SAL_CALL getImplementationName( ) throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
74 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
75 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
77 // XNameContainer
78 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
79 virtual void SAL_CALL removeByName( const OUString& Name ) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
81 // XNameReplace
82 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
84 // XNameAccess
85 virtual uno::Any SAL_CALL getByName( const OUString& aName ) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
86 virtual uno::Sequence< OUString > SAL_CALL getElementNames( ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
87 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
89 // XElementAccess
90 virtual uno::Type SAL_CALL getElementType( ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
91 virtual sal_Bool SAL_CALL hasElements( ) throw( uno::RuntimeException, std::exception) SAL_OVERRIDE;
94 SvxUnoMarkerTable::SvxUnoMarkerTable( SdrModel* pModel ) throw()
95 : mpModel( pModel ),
96 mpModelPool( pModel ? &pModel->GetItemPool() : (SfxItemPool*)NULL )
98 if( pModel )
99 StartListening( *pModel );
102 SvxUnoMarkerTable::~SvxUnoMarkerTable() throw()
104 if( mpModel )
105 EndListening( *mpModel );
106 dispose();
109 void SvxUnoMarkerTable::dispose()
111 ItemPoolVector::iterator aIter = maItemSetVector.begin();
112 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
114 while( aIter != aEnd )
116 delete (*aIter++);
119 maItemSetVector.clear();
122 // SfxListener
123 void SvxUnoMarkerTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
125 const SdrHint* pSdrHint = dynamic_cast<const SdrHint*>(&rHint);
127 if( pSdrHint && HINT_MODELCLEARED == pSdrHint->GetKind() )
128 dispose();
131 sal_Bool SAL_CALL SvxUnoMarkerTable::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException, std::exception)
133 return cppu::supportsService(this, ServiceName);
136 OUString SAL_CALL SvxUnoMarkerTable::getImplementationName() throw( uno::RuntimeException, std::exception )
138 return OUString("SvxUnoMarkerTable");
141 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getSupportedServiceNames( )
142 throw( uno::RuntimeException, std::exception )
144 uno::Sequence< OUString > aSNS( 1 );
145 aSNS.getArray()[0] = "com.sun.star.drawing.MarkerTable";
146 return aSNS;
149 void SAL_CALL SvxUnoMarkerTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
151 SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, XATTR_LINESTART, XATTR_LINEEND );
152 maItemSetVector.push_back( mpInSet );
154 XLineEndItem aEndMarker;
155 aEndMarker.SetName( aName );
156 aEndMarker.PutValue( aElement );
158 mpInSet->Put( aEndMarker, XATTR_LINEEND );
160 XLineStartItem aStartMarker;
161 aStartMarker.SetName( aName );
162 aStartMarker.PutValue( aElement );
164 mpInSet->Put( aStartMarker, XATTR_LINESTART );
167 // XNameContainer
168 void SAL_CALL SvxUnoMarkerTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
169 throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
171 SolarMutexGuard aGuard;
173 if( hasByName( aApiName ) )
174 throw container::ElementExistException();
176 OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
178 ImplInsertByName( aName, aElement );
181 void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName )
182 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
184 SolarMutexGuard aGuard;
186 // a little quickfix for 2.0 to let applications clear api
187 // created items that are not used
188 if ( aApiName == "~clear~" )
190 dispose();
191 return;
194 OUString Name = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
196 ItemPoolVector::iterator aIter = maItemSetVector.begin();
197 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
199 const OUString aSearchName( Name );
201 while( aIter != aEnd )
203 const NameOrIndex *pItem = static_cast<const NameOrIndex *>(&((*aIter)->Get( XATTR_LINEEND ) ));
204 if( pItem->GetName() == aSearchName )
206 delete (*aIter);
207 maItemSetVector.erase( aIter );
208 return;
210 ++aIter;
213 if( !hasByName( Name ) )
214 throw container::NoSuchElementException();
217 // XNameReplace
218 void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
219 throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
221 SolarMutexGuard aGuard;
223 OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
225 ItemPoolVector::iterator aIter = maItemSetVector.begin();
226 const ItemPoolVector::iterator aEnd = maItemSetVector.end();
228 const OUString aSearchName( aName );
230 while( aIter != aEnd )
232 const NameOrIndex *pItem = static_cast<const NameOrIndex *>(&((*aIter)->Get( XATTR_LINEEND ) ));
233 if( pItem->GetName() == aSearchName )
235 XLineEndItem aEndMarker;
236 aEndMarker.SetName( aSearchName );
237 if( !aEndMarker.PutValue( aElement ) )
238 throw lang::IllegalArgumentException();
240 (*aIter)->Put( aEndMarker, XATTR_LINEEND );
242 XLineStartItem aStartMarker;
243 aStartMarker.SetName( aSearchName );
244 aStartMarker.PutValue( aElement );
246 (*aIter)->Put( aStartMarker, XATTR_LINESTART );
247 return;
249 ++aIter;
252 // if it is not in our own sets, modify the pool!
253 bool bFound = false;
255 sal_uInt32 nSurrogate;
256 const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
257 for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
259 NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate)));
260 if( pItem && pItem->GetName() == aSearchName )
262 pItem->PutValue( aElement );
263 bFound = true;
264 break;
268 const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
269 for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
271 NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate)));
272 if( pItem && pItem->GetName() == aSearchName )
274 pItem->PutValue( aElement );
275 bFound = true;
276 break;
280 if( bFound )
281 ImplInsertByName( aName, aElement );
282 else
283 throw container::NoSuchElementException();
286 static bool getByNameFromPool( const OUString& rSearchName, SfxItemPool* pPool, sal_uInt16 nWhich, uno::Any& rAny )
288 const sal_uInt32 nSurrogateCount = pPool ? pPool->GetItemCount2( nWhich ) : 0;
289 for( sal_uInt32 nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
291 const NameOrIndex *pItem = static_cast<const NameOrIndex*>(pPool->GetItem2( nWhich, nSurrogate ));
293 if( pItem && pItem->GetName() == rSearchName )
295 pItem->QueryValue( rAny, 0 );
296 return true;
300 return false;
303 // XNameAccess
304 uno::Any SAL_CALL SvxUnoMarkerTable::getByName( const OUString& aApiName )
305 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
307 SolarMutexGuard aGuard;
309 OUString aName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aApiName);
311 uno::Any aAny;
313 if (mpModelPool && !aName.isEmpty())
317 if (getByNameFromPool(aName, mpModelPool, XATTR_LINESTART, aAny))
318 break;
320 if (getByNameFromPool(aName, mpModelPool, XATTR_LINEEND, aAny))
321 break;
323 throw container::NoSuchElementException();
325 while(false);
328 return aAny;
331 static void createNamesForPool( SfxItemPool* pPool, sal_uInt16 nWhich, std::set< OUString >& rNameSet )
333 const sal_uInt32 nSuroCount = pPool->GetItemCount2( nWhich );
335 for(sal_uInt32 nSurrogate = 0; nSurrogate < nSuroCount; ++nSurrogate)
337 const NameOrIndex* pItem = static_cast<const NameOrIndex*>(pPool->GetItem2( nWhich, nSurrogate ));
339 if( pItem == NULL || pItem->GetName().isEmpty() )
340 continue;
342 OUString aName = SvxUnogetApiNameForItem(XATTR_LINEEND, pItem->GetName());
343 rNameSet.insert( aName );
347 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getElementNames()
348 throw( uno::RuntimeException, std::exception )
350 SolarMutexGuard aGuard;
352 std::set< OUString > aNameSet;
354 // search model pool for line starts
355 createNamesForPool( mpModelPool, XATTR_LINESTART, aNameSet );
357 // search model pool for line ends
358 createNamesForPool( mpModelPool, XATTR_LINEEND, aNameSet );
360 uno::Sequence< OUString > aSeq( aNameSet.size() );
361 OUString* pNames = aSeq.getArray();
363 std::set< OUString >::iterator aIter( aNameSet.begin() );
364 const std::set< OUString >::iterator aEnd( aNameSet.end() );
366 while( aIter != aEnd )
368 *pNames++ = *aIter++;
371 return aSeq;
374 sal_Bool SAL_CALL SvxUnoMarkerTable::hasByName( const OUString& aName )
375 throw( uno::RuntimeException, std::exception )
377 SolarMutexGuard aGuard;
379 if( aName.isEmpty() )
380 return sal_False;
382 OUString aSearchName;
384 const NameOrIndex *pItem;
386 aSearchName = SvxUnogetInternalNameForItem(XATTR_LINESTART, aName);
387 sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
388 sal_uInt32 nSurrogate;
389 for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
391 pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate));
392 if( pItem && pItem->GetName() == aSearchName )
393 return sal_True;
396 aSearchName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aName);
397 sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
398 for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
400 pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate));
401 if( pItem && pItem->GetName() == aSearchName )
402 return sal_True;
405 return sal_False;
408 // XElementAccess
409 uno::Type SAL_CALL SvxUnoMarkerTable::getElementType( )
410 throw( uno::RuntimeException, std::exception )
412 return cppu::UnoType<drawing::PointSequence>::get();
415 sal_Bool SAL_CALL SvxUnoMarkerTable::hasElements( )
416 throw( uno::RuntimeException, std::exception )
418 SolarMutexGuard aGuard;
420 const NameOrIndex *pItem;
422 const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
423 sal_uInt32 nSurrogate;
424 for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
426 pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate));
427 if( pItem && !pItem->GetName().isEmpty() )
428 return sal_True;
431 const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
432 for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
434 pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate));
435 if( pItem && !pItem->GetName().isEmpty() )
436 return sal_True;
439 return sal_False;
443 * Create a hatchtable
445 uno::Reference< uno::XInterface > SAL_CALL SvxUnoMarkerTable_createInstance( SdrModel* pModel )
447 return *new SvxUnoMarkerTable(pModel);
452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */