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 <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>
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
>,
58 SfxItemPool
* mpModelPool
;
60 ItemPoolVector maItemSetVector
;
63 SvxUnoMarkerTable( SdrModel
* pModel
) throw();
64 virtual ~SvxUnoMarkerTable() throw();
69 virtual void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
) throw ();
71 void SAL_CALL
ImplInsertByName( const OUString
& aName
, const uno::Any
& aElement
);
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
);
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
);
83 virtual void SAL_CALL
replaceByName( const OUString
& aName
, const uno::Any
& aElement
) throw( lang::IllegalArgumentException
, container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
);
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
);
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()
97 mpModelPool( pModel
? &pModel
->GetItemPool() : (SfxItemPool
*)NULL
)
100 StartListening( *pModel
);
103 SvxUnoMarkerTable::~SvxUnoMarkerTable() throw()
106 EndListening( *mpModel
);
110 void SvxUnoMarkerTable::dispose()
112 ItemPoolVector::iterator aIter
= maItemSetVector
.begin();
113 const ItemPoolVector::iterator aEnd
= maItemSetVector
.end();
115 while( aIter
!= aEnd
)
120 maItemSetVector
.clear();
124 void SvxUnoMarkerTable::Notify( SfxBroadcaster
&, const SfxHint
& rHint
) throw()
126 const SdrHint
* pSdrHint
= PTR_CAST( SdrHint
, &rHint
);
128 if( pSdrHint
&& HINT_MODELCLEARED
== pSdrHint
->GetKind() )
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
)
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" );
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
);
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~" )
202 OUString Name
= SvxUnogetInternalNameForItem(XATTR_LINEEND
, aApiName
);
204 ItemPoolVector::iterator aIter
= maItemSetVector
.begin();
205 const ItemPoolVector::iterator aEnd
= maItemSetVector
.end();
208 const String
aSearchName( Name
);
210 while( aIter
!= aEnd
)
212 pItem
= (NameOrIndex
*)&((*aIter
)->Get( XATTR_LINEEND
) );
213 if( pItem
->GetName() == aSearchName
)
216 maItemSetVector
.erase( aIter
);
222 if( !hasByName( Name
) )
223 throw container::NoSuchElementException();
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();
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
);
262 // if it is not in our own sets, modify the pool!
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
);
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
);
291 ImplInsertByName( aName
, aElement
);
293 throw container::NoSuchElementException();
296 static bool getByNameFromPool( const String
& rSearchName
, SfxItemPool
* pPool
, sal_uInt16 nWhich
, uno::Any
& rAny
)
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 );
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
);
324 if (mpModelPool
&& !aName
.isEmpty())
328 if (getByNameFromPool(aName
, mpModelPool
, XATTR_LINESTART
, aAny
))
331 if (getByNameFromPool(aName
, mpModelPool
, XATTR_LINEEND
, aAny
))
334 throw container::NoSuchElementException();
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 )
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
++;
385 sal_Bool SAL_CALL
SvxUnoMarkerTable::hasByName( const OUString
& aName
)
386 throw( uno::RuntimeException
)
388 SolarMutexGuard aGuard
;
390 if( aName
.isEmpty() )
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
)
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
)
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
;
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 )
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 )
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: */