1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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>
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
>,
57 SfxItemPool
* mpModelPool
;
59 ItemPoolVector maItemSetVector
;
62 SvxUnoMarkerTable( SdrModel
* pModel
) throw();
63 virtual ~SvxUnoMarkerTable() throw();
68 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) throw () SAL_OVERRIDE
;
70 void SAL_CALL
ImplInsertByName( const OUString
& aName
, const uno::Any
& aElement
);
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
;
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
;
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
;
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
;
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()
96 mpModelPool( pModel
? &pModel
->GetItemPool() : (SfxItemPool
*)NULL
)
99 StartListening( *pModel
);
102 SvxUnoMarkerTable::~SvxUnoMarkerTable() throw()
105 EndListening( *mpModel
);
109 void SvxUnoMarkerTable::dispose()
111 ItemPoolVector::iterator aIter
= maItemSetVector
.begin();
112 const ItemPoolVector::iterator aEnd
= maItemSetVector
.end();
114 while( aIter
!= aEnd
)
119 maItemSetVector
.clear();
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() )
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";
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
);
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~" )
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
)
207 maItemSetVector
.erase( aIter
);
213 if( !hasByName( Name
) )
214 throw container::NoSuchElementException();
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
);
252 // if it is not in our own sets, modify the pool!
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
);
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
);
281 ImplInsertByName( aName
, aElement
);
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 );
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
);
313 if (mpModelPool
&& !aName
.isEmpty())
317 if (getByNameFromPool(aName
, mpModelPool
, XATTR_LINESTART
, aAny
))
320 if (getByNameFromPool(aName
, mpModelPool
, XATTR_LINEEND
, aAny
))
323 throw container::NoSuchElementException();
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() )
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
++;
374 sal_Bool SAL_CALL
SvxUnoMarkerTable::hasByName( const OUString
& aName
)
375 throw( uno::RuntimeException
, std::exception
)
377 SolarMutexGuard aGuard
;
379 if( aName
.isEmpty() )
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
)
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
)
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() )
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() )
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: */