xref: /AOO41X/main/svx/source/unodraw/unomtabl.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
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 <comphelper/stl_types.hxx>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/drawing/PointSequence.hpp>
32 #include <svl/style.hxx>
33 
34 #include <cppuhelper/implbase2.hxx>
35 #include <svl/itempool.hxx>
36 #include <svl/itemset.hxx>
37 #include <svl/lstner.hxx>
38 #include <svx/xlnedit.hxx>
39 #include <svx/xlnstit.hxx>
40 #include <svx/svdmodel.hxx>
41 #include <svx/xdef.hxx>
42 #include <svx/xflhtit.hxx>
43 
44 #include <vector>
45 #include <vos/mutex.hxx>
46 #include <vcl/svapp.hxx>
47 
48 
49 #include "svx/unofill.hxx"
50 
51 #include "svx/unoapi.hxx"
52 
53 using namespace ::com::sun::star;
54 using namespace ::rtl;
55 using namespace ::cppu;
56 using namespace ::vos;
57 
58 typedef std::vector< SfxItemSet* > ItemPoolVector;
59 
60 class SvxUnoMarkerTable : public WeakImplHelper2< container::XNameContainer, lang::XServiceInfo >,
61                           public SfxListener
62 {
63 private:
64     SdrModel*       mpModel;
65     SfxItemPool*    mpModelPool;
66 
67     ItemPoolVector maItemSetVector;
68 
69 public:
70     SvxUnoMarkerTable( SdrModel* pModel ) throw();
71     virtual ~SvxUnoMarkerTable() throw();
72 
73     void dispose();
74 
75     // SfxListener
76     virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw ();
77 
78     void SAL_CALL ImplInsertByName( const OUString& aName, const uno::Any& aElement );
79 
80     // XServiceInfo
81     virtual OUString SAL_CALL getImplementationName(  ) throw( uno::RuntimeException );
82     virtual sal_Bool SAL_CALL supportsService( const  OUString& ServiceName ) throw( uno::RuntimeException);
83     virtual uno::Sequence<  OUString > SAL_CALL getSupportedServiceNames(  ) throw( uno::RuntimeException);
84 
85     // XNameContainer
86     virtual void SAL_CALL insertByName( const  OUString& aName, const  uno::Any& aElement ) throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException);
87     virtual void SAL_CALL removeByName( const  OUString& Name ) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
88 
89     // XNameReplace
90     virtual void SAL_CALL replaceByName( const  OUString& aName, const  uno::Any& aElement ) throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
91 
92     // XNameAccess
93     virtual uno::Any SAL_CALL getByName( const  OUString& aName ) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
94     virtual uno::Sequence<  OUString > SAL_CALL getElementNames(  ) throw( uno::RuntimeException);
95     virtual sal_Bool SAL_CALL hasByName( const  OUString& aName ) throw( uno::RuntimeException);
96 
97     // XElementAccess
98     virtual uno::Type SAL_CALL getElementType(  ) throw( uno::RuntimeException);
99     virtual sal_Bool SAL_CALL hasElements(  ) throw( uno::RuntimeException);
100 };
101 
SvxUnoMarkerTable(SdrModel * pModel)102 SvxUnoMarkerTable::SvxUnoMarkerTable( SdrModel* pModel ) throw()
103 : mpModel( pModel ),
104   mpModelPool( pModel ? &pModel->GetItemPool() : (SfxItemPool*)NULL )
105 {
106     if( pModel )
107         StartListening( *pModel );
108 }
109 
~SvxUnoMarkerTable()110 SvxUnoMarkerTable::~SvxUnoMarkerTable() throw()
111 {
112     if( mpModel )
113         EndListening( *mpModel );
114     dispose();
115 }
116 
dispose()117 void SvxUnoMarkerTable::dispose()
118 {
119     ItemPoolVector::iterator aIter = maItemSetVector.begin();
120     const ItemPoolVector::iterator aEnd = maItemSetVector.end();
121 
122     while( aIter != aEnd )
123     {
124         delete (*aIter++);
125     }
126 
127     maItemSetVector.clear();
128 }
129 
130 // SfxListener
Notify(SfxBroadcaster &,const SfxHint & rHint)131 void SvxUnoMarkerTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
132 {
133     const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
134 
135     if( pSdrHint && HINT_MODELCLEARED == pSdrHint->GetKind() )
136         dispose();
137 }
138 
supportsService(const OUString & ServiceName)139 sal_Bool SAL_CALL SvxUnoMarkerTable::supportsService( const  OUString& ServiceName ) throw(uno::RuntimeException)
140 {
141     uno::Sequence< OUString > aSNL( getSupportedServiceNames() );
142     const OUString * pArray = aSNL.getConstArray();
143 
144     for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
145         if( pArray[i] == ServiceName )
146             return sal_True;
147 
148     return sal_False;
149 }
150 
getImplementationName()151 OUString SAL_CALL SvxUnoMarkerTable::getImplementationName() throw( uno::RuntimeException )
152 {
153     return OUString( RTL_CONSTASCII_USTRINGPARAM("SvxUnoMarkerTable") );
154 }
155 
getSupportedServiceNames()156 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getSupportedServiceNames(  )
157     throw( uno::RuntimeException )
158 {
159     uno::Sequence< OUString > aSNS( 1 );
160     aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.MarkerTable" ));
161     return aSNS;
162 }
163 
ImplInsertByName(const OUString & aName,const uno::Any & aElement)164 void SAL_CALL SvxUnoMarkerTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
165 {
166     SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, XATTR_LINESTART, XATTR_LINEEND );
167     maItemSetVector.push_back( mpInSet );
168 
169     XLineEndItem aEndMarker;
170     aEndMarker.SetName( String( aName ) );
171     aEndMarker.PutValue( aElement );
172 
173     mpInSet->Put( aEndMarker, XATTR_LINEEND );
174 
175     XLineStartItem aStartMarker;
176     aStartMarker.SetName( String( aName ) );
177     aStartMarker.PutValue( aElement );
178 
179     mpInSet->Put( aStartMarker, XATTR_LINESTART );
180 }
181 
182 // XNameContainer
insertByName(const OUString & aApiName,const uno::Any & aElement)183 void SAL_CALL SvxUnoMarkerTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
184     throw( lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException )
185 {
186     OGuard aGuard( Application::GetSolarMutex() );
187 
188     if( hasByName( aApiName ) )
189         throw container::ElementExistException();
190 
191     String aName;
192     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, aName );
193 
194     ImplInsertByName( aName, aElement );
195 }
196 
removeByName(const OUString & aApiName)197 void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName )
198     throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
199 {
200     OGuard aGuard( Application::GetSolarMutex() );
201 
202     // a little quickfix for 2.0 to let applications clear api
203     // created items that are not used
204     if( aApiName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("~clear~") ) )
205     {
206         dispose();
207         return;
208     }
209 
210     String Name;
211     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, Name );
212 
213     ItemPoolVector::iterator aIter = maItemSetVector.begin();
214     const ItemPoolVector::iterator aEnd = maItemSetVector.end();
215 
216     NameOrIndex *pItem;
217     const String aSearchName( Name );
218 
219     while( aIter != aEnd )
220     {
221         pItem = (NameOrIndex *)&((*aIter)->Get( XATTR_LINEEND ) );
222         if( pItem->GetName() == aSearchName )
223         {
224             delete (*aIter);
225             maItemSetVector.erase( aIter );
226             return;
227         }
228         aIter++;
229     }
230 
231     if( !hasByName( Name ) )
232         throw container::NoSuchElementException();
233 }
234 
235 // XNameReplace
replaceByName(const OUString & aApiName,const uno::Any & aElement)236 void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
237     throw( lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
238 {
239     OGuard aGuard( Application::GetSolarMutex() );
240 
241     String aName;
242     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, aName );
243 
244     ItemPoolVector::iterator aIter = maItemSetVector.begin();
245     const ItemPoolVector::iterator aEnd = maItemSetVector.end();
246 
247     NameOrIndex *pItem;
248     const String aSearchName( aName );
249 
250     while( aIter != aEnd )
251     {
252         pItem = (NameOrIndex *)&((*aIter)->Get( XATTR_LINEEND ) );
253         if( pItem->GetName() == aSearchName )
254         {
255             XLineEndItem aEndMarker;
256             aEndMarker.SetName( aSearchName );
257             if( !aEndMarker.PutValue( aElement ) )
258                 throw lang::IllegalArgumentException();
259 
260             (*aIter)->Put( aEndMarker, XATTR_LINEEND );
261 
262             XLineStartItem aStartMarker;
263             aStartMarker.SetName( aSearchName );
264             aStartMarker.PutValue( aElement );
265 
266             (*aIter)->Put( aStartMarker, XATTR_LINESTART );
267             return;
268         }
269         aIter++;
270     }
271 
272     // if it is not in our own sets, modify the pool!
273     sal_Bool bFound = sal_False;
274 
275     sal_uInt32 nSurrogate;
276     const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
277     for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
278     {
279         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
280         if( pItem && pItem->GetName() == aSearchName )
281         {
282             pItem->PutValue( aElement );
283             bFound = sal_True;
284             break;
285         }
286     }
287 
288     const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
289     for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
290     {
291         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
292         if( pItem && pItem->GetName() == aSearchName )
293         {
294             pItem->PutValue( aElement );
295             bFound = sal_True;
296             break;
297         }
298     }
299 
300     if( bFound )
301         ImplInsertByName( aName, aElement );
302     else
303         throw container::NoSuchElementException();
304 }
305 
getByNameFromPool(const String & rSearchName,SfxItemPool * pPool,sal_uInt16 nWhich,uno::Any & rAny)306 static sal_Bool getByNameFromPool( const String& rSearchName, SfxItemPool* pPool, sal_uInt16 nWhich, uno::Any& rAny )
307 {
308     NameOrIndex *pItem;
309     const sal_uInt32 nSurrogateCount = pPool ? pPool->GetItemCount2( nWhich ) : 0;
310     for( sal_uInt32 nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
311     {
312         pItem = (NameOrIndex*)pPool->GetItem2( nWhich, nSurrogate );
313 
314         if( pItem && pItem->GetName() == rSearchName )
315         {
316             pItem->QueryValue( rAny, 0 );
317             return sal_True;
318         }
319     }
320 
321     return sal_False;
322 }
323 
324 // XNameAccess
getByName(const OUString & aApiName)325 uno::Any SAL_CALL SvxUnoMarkerTable::getByName( const OUString& aApiName )
326     throw( container::NoSuchElementException,  lang::WrappedTargetException, uno::RuntimeException)
327 {
328     OGuard aGuard( Application::GetSolarMutex() );
329 
330     String aName;
331     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, aName );
332 
333     uno::Any aAny;
334 
335     if( mpModelPool && aName.Len() != 0 )
336     {
337         do
338         {
339             const String aSearchName( aName );
340             if( getByNameFromPool( aSearchName, mpModelPool, XATTR_LINESTART, aAny ) )
341                 break;
342 
343             if( getByNameFromPool( aSearchName, mpModelPool, XATTR_LINEEND, aAny ) )
344                 break;
345 
346             throw container::NoSuchElementException();
347         }
348         while(0);
349     }
350 
351     return aAny;
352 }
353 
createNamesForPool(SfxItemPool * pPool,sal_uInt16 nWhich,std::set<OUString,comphelper::UStringLess> & rNameSet)354 static void createNamesForPool( SfxItemPool* pPool, sal_uInt16 nWhich, std::set< OUString, comphelper::UStringLess >& rNameSet )
355 {
356     const sal_uInt32 nSuroCount = pPool->GetItemCount2( nWhich );
357     sal_uInt32 nSurrogate;
358 
359     NameOrIndex* pItem;
360     OUString aName;
361 
362     for( nSurrogate = 0; nSurrogate < nSuroCount; nSurrogate++ )
363     {
364         pItem = (NameOrIndex*)pPool->GetItem2( nWhich, nSurrogate );
365 
366         if( pItem == NULL || pItem->GetName().Len() == 0 )
367             continue;
368 
369         SvxUnogetApiNameForItem( XATTR_LINEEND, pItem->GetName(), aName );
370         rNameSet.insert( aName );
371     }
372 }
373 
getElementNames()374 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getElementNames()
375     throw( uno::RuntimeException )
376 {
377     OGuard aGuard( Application::GetSolarMutex() );
378 
379     std::set< OUString, comphelper::UStringLess > aNameSet;
380 
381     // search model pool for line starts
382     createNamesForPool( mpModelPool, XATTR_LINESTART, aNameSet );
383 
384     // search model pool for line ends
385     createNamesForPool( mpModelPool, XATTR_LINEEND, aNameSet );
386 
387     uno::Sequence< OUString > aSeq( aNameSet.size() );
388     OUString* pNames = aSeq.getArray();
389 
390     std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() );
391     const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() );
392 
393     while( aIter != aEnd )
394     {
395         *pNames++ = *aIter++;
396     }
397 
398     return aSeq;
399 }
400 
hasByName(const OUString & aName)401 sal_Bool SAL_CALL SvxUnoMarkerTable::hasByName( const OUString& aName )
402     throw( uno::RuntimeException )
403 {
404     OGuard aGuard( Application::GetSolarMutex() );
405 
406     if( aName.getLength() == 0 )
407         return sal_False;
408 
409     String aSearchName;
410 
411     NameOrIndex *pItem;
412 
413     SvxUnogetInternalNameForItem( XATTR_LINESTART, aName, aSearchName );
414     sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
415     sal_uInt32 nSurrogate;
416     for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
417     {
418         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
419         if( pItem && pItem->GetName() == aSearchName )
420             return sal_True;
421     }
422 
423     SvxUnogetInternalNameForItem( XATTR_LINEEND, aName, aSearchName );
424     sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
425     for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
426     {
427         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
428         if( pItem && pItem->GetName() == aSearchName )
429             return sal_True;
430     }
431 
432     return sal_False;
433 }
434 
435 // XElementAccess
getElementType()436 uno::Type SAL_CALL SvxUnoMarkerTable::getElementType(  )
437     throw( uno::RuntimeException )
438 {
439     return ::getCppuType((const drawing::PointSequence*)0);
440 }
441 
hasElements()442 sal_Bool SAL_CALL SvxUnoMarkerTable::hasElements(  )
443     throw( uno::RuntimeException )
444 {
445     OGuard aGuard( Application::GetSolarMutex() );
446 
447     NameOrIndex *pItem;
448 
449     const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
450     sal_uInt32 nSurrogate;
451     for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
452     {
453         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
454         if( pItem && pItem->GetName().Len() != 0 )
455             return sal_True;
456     }
457 
458     const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
459     for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
460     {
461         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
462         if( pItem && pItem->GetName().Len() != 0 )
463             return sal_True;
464     }
465 
466     return sal_False;
467 }
468 
469 /**
470  * Create a hatchtable
471  */
SvxUnoMarkerTable_createInstance(SdrModel * pModel)472 uno::Reference< uno::XInterface > SAL_CALL SvxUnoMarkerTable_createInstance( SdrModel* pModel )
473 {
474     return *new SvxUnoMarkerTable(pModel);
475 }
476 
477 
478 
479