xref: /trunk/main/svx/source/unodraw/unomtabl.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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(  );
82     virtual sal_Bool SAL_CALL supportsService( const  OUString& ServiceName );
83     virtual uno::Sequence<  OUString > SAL_CALL getSupportedServiceNames(  );
84 
85     // XNameContainer
86     virtual void SAL_CALL insertByName( const  OUString& aName, const  uno::Any& aElement );
87     virtual void SAL_CALL removeByName( const  OUString& Name );
88 
89     // XNameReplace
90     virtual void SAL_CALL replaceByName( const  OUString& aName, const  uno::Any& aElement );
91 
92     // XNameAccess
93     virtual uno::Any SAL_CALL getByName( const  OUString& aName );
94     virtual uno::Sequence<  OUString > SAL_CALL getElementNames(  );
95     virtual sal_Bool SAL_CALL hasByName( const  OUString& aName );
96 
97     // XElementAccess
98     virtual uno::Type SAL_CALL getElementType(  );
99     virtual sal_Bool SAL_CALL hasElements(  );
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 )
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()
152 {
153     return OUString( RTL_CONSTASCII_USTRINGPARAM("SvxUnoMarkerTable") );
154 }
155 
getSupportedServiceNames()156 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getSupportedServiceNames(  )
157 {
158     uno::Sequence< OUString > aSNS( 1 );
159     aSNS.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.MarkerTable" ));
160     return aSNS;
161 }
162 
ImplInsertByName(const OUString & aName,const uno::Any & aElement)163 void SAL_CALL SvxUnoMarkerTable::ImplInsertByName( const OUString& aName, const uno::Any& aElement )
164 {
165     SfxItemSet* mpInSet = new SfxItemSet( *mpModelPool, XATTR_LINESTART, XATTR_LINEEND );
166     maItemSetVector.push_back( mpInSet );
167 
168     XLineEndItem aEndMarker;
169     aEndMarker.SetName( String( aName ) );
170     aEndMarker.PutValue( aElement );
171 
172     mpInSet->Put( aEndMarker, XATTR_LINEEND );
173 
174     XLineStartItem aStartMarker;
175     aStartMarker.SetName( String( aName ) );
176     aStartMarker.PutValue( aElement );
177 
178     mpInSet->Put( aStartMarker, XATTR_LINESTART );
179 }
180 
181 // XNameContainer
insertByName(const OUString & aApiName,const uno::Any & aElement)182 void SAL_CALL SvxUnoMarkerTable::insertByName( const OUString& aApiName, const uno::Any& aElement )
183 {
184     OGuard aGuard( Application::GetSolarMutex() );
185 
186     if( hasByName( aApiName ) )
187         throw container::ElementExistException();
188 
189     String aName;
190     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, aName );
191 
192     ImplInsertByName( aName, aElement );
193 }
194 
removeByName(const OUString & aApiName)195 void SAL_CALL SvxUnoMarkerTable::removeByName( const OUString& aApiName )
196 {
197     OGuard aGuard( Application::GetSolarMutex() );
198 
199     // a little quickfix for 2.0 to let applications clear api
200     // created items that are not used
201     if( aApiName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("~clear~") ) )
202     {
203         dispose();
204         return;
205     }
206 
207     String Name;
208     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, Name );
209 
210     ItemPoolVector::iterator aIter = maItemSetVector.begin();
211     const ItemPoolVector::iterator aEnd = maItemSetVector.end();
212 
213     NameOrIndex *pItem;
214     const String aSearchName( Name );
215 
216     while( aIter != aEnd )
217     {
218         pItem = (NameOrIndex *)&((*aIter)->Get( XATTR_LINEEND ) );
219         if( pItem->GetName() == aSearchName )
220         {
221             delete (*aIter);
222             maItemSetVector.erase( aIter );
223             return;
224         }
225         aIter++;
226     }
227 
228     if( !hasByName( Name ) )
229         throw container::NoSuchElementException();
230 }
231 
232 // XNameReplace
replaceByName(const OUString & aApiName,const uno::Any & aElement)233 void SAL_CALL SvxUnoMarkerTable::replaceByName( const OUString& aApiName, const uno::Any& aElement )
234 {
235     OGuard aGuard( Application::GetSolarMutex() );
236 
237     String aName;
238     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, aName );
239 
240     ItemPoolVector::iterator aIter = maItemSetVector.begin();
241     const ItemPoolVector::iterator aEnd = maItemSetVector.end();
242 
243     NameOrIndex *pItem;
244     const String aSearchName( aName );
245 
246     while( aIter != aEnd )
247     {
248         pItem = (NameOrIndex *)&((*aIter)->Get( XATTR_LINEEND ) );
249         if( pItem->GetName() == aSearchName )
250         {
251             XLineEndItem aEndMarker;
252             aEndMarker.SetName( aSearchName );
253             if( !aEndMarker.PutValue( aElement ) )
254                 throw lang::IllegalArgumentException();
255 
256             (*aIter)->Put( aEndMarker, XATTR_LINEEND );
257 
258             XLineStartItem aStartMarker;
259             aStartMarker.SetName( aSearchName );
260             aStartMarker.PutValue( aElement );
261 
262             (*aIter)->Put( aStartMarker, XATTR_LINESTART );
263             return;
264         }
265         aIter++;
266     }
267 
268     // if it is not in our own sets, modify the pool!
269     sal_Bool bFound = sal_False;
270 
271     sal_uInt32 nSurrogate;
272     const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
273     for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
274     {
275         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
276         if( pItem && pItem->GetName() == aSearchName )
277         {
278             pItem->PutValue( aElement );
279             bFound = sal_True;
280             break;
281         }
282     }
283 
284     const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
285     for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
286     {
287         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
288         if( pItem && pItem->GetName() == aSearchName )
289         {
290             pItem->PutValue( aElement );
291             bFound = sal_True;
292             break;
293         }
294     }
295 
296     if( bFound )
297         ImplInsertByName( aName, aElement );
298     else
299         throw container::NoSuchElementException();
300 }
301 
getByNameFromPool(const String & rSearchName,SfxItemPool * pPool,sal_uInt16 nWhich,uno::Any & rAny)302 static sal_Bool getByNameFromPool( const String& rSearchName, SfxItemPool* pPool, sal_uInt16 nWhich, uno::Any& rAny )
303 {
304     NameOrIndex *pItem;
305     const sal_uInt32 nSurrogateCount = pPool ? pPool->GetItemCount2( nWhich ) : 0;
306     for( sal_uInt32 nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
307     {
308         pItem = (NameOrIndex*)pPool->GetItem2( nWhich, nSurrogate );
309 
310         if( pItem && pItem->GetName() == rSearchName )
311         {
312             pItem->QueryValue( rAny, 0 );
313             return sal_True;
314         }
315     }
316 
317     return sal_False;
318 }
319 
320 // XNameAccess
getByName(const OUString & aApiName)321 uno::Any SAL_CALL SvxUnoMarkerTable::getByName( const OUString& aApiName )
322 {
323     OGuard aGuard( Application::GetSolarMutex() );
324 
325     String aName;
326     SvxUnogetInternalNameForItem( XATTR_LINEEND, aApiName, aName );
327 
328     uno::Any aAny;
329 
330     if( mpModelPool && aName.Len() != 0 )
331     {
332         do
333         {
334             const String aSearchName( aName );
335             if( getByNameFromPool( aSearchName, mpModelPool, XATTR_LINESTART, aAny ) )
336                 break;
337 
338             if( getByNameFromPool( aSearchName, mpModelPool, XATTR_LINEEND, aAny ) )
339                 break;
340 
341             throw container::NoSuchElementException();
342         }
343         while(0);
344     }
345 
346     return aAny;
347 }
348 
createNamesForPool(SfxItemPool * pPool,sal_uInt16 nWhich,std::set<OUString,comphelper::UStringLess> & rNameSet)349 static void createNamesForPool( SfxItemPool* pPool, sal_uInt16 nWhich, std::set< OUString, comphelper::UStringLess >& rNameSet )
350 {
351     const sal_uInt32 nSuroCount = pPool->GetItemCount2( nWhich );
352     sal_uInt32 nSurrogate;
353 
354     NameOrIndex* pItem;
355     OUString aName;
356 
357     for( nSurrogate = 0; nSurrogate < nSuroCount; nSurrogate++ )
358     {
359         pItem = (NameOrIndex*)pPool->GetItem2( nWhich, nSurrogate );
360 
361         if( pItem == NULL || pItem->GetName().Len() == 0 )
362             continue;
363 
364         SvxUnogetApiNameForItem( XATTR_LINEEND, pItem->GetName(), aName );
365         rNameSet.insert( aName );
366     }
367 }
368 
getElementNames()369 uno::Sequence< OUString > SAL_CALL SvxUnoMarkerTable::getElementNames()
370 {
371     OGuard aGuard( Application::GetSolarMutex() );
372 
373     std::set< OUString, comphelper::UStringLess > aNameSet;
374 
375     // search model pool for line starts
376     createNamesForPool( mpModelPool, XATTR_LINESTART, aNameSet );
377 
378     // search model pool for line ends
379     createNamesForPool( mpModelPool, XATTR_LINEEND, aNameSet );
380 
381     uno::Sequence< OUString > aSeq( aNameSet.size() );
382     OUString* pNames = aSeq.getArray();
383 
384     std::set< OUString, comphelper::UStringLess >::iterator aIter( aNameSet.begin() );
385     const std::set< OUString, comphelper::UStringLess >::iterator aEnd( aNameSet.end() );
386 
387     while( aIter != aEnd )
388     {
389         *pNames++ = *aIter++;
390     }
391 
392     return aSeq;
393 }
394 
hasByName(const OUString & aName)395 sal_Bool SAL_CALL SvxUnoMarkerTable::hasByName( const OUString& aName )
396 {
397     OGuard aGuard( Application::GetSolarMutex() );
398 
399     if( aName.getLength() == 0 )
400         return sal_False;
401 
402     String aSearchName;
403 
404     NameOrIndex *pItem;
405 
406     SvxUnogetInternalNameForItem( XATTR_LINESTART, aName, aSearchName );
407     sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
408     sal_uInt32 nSurrogate;
409     for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
410     {
411         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
412         if( pItem && pItem->GetName() == aSearchName )
413             return sal_True;
414     }
415 
416     SvxUnogetInternalNameForItem( XATTR_LINEEND, aName, aSearchName );
417     sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
418     for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
419     {
420         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
421         if( pItem && pItem->GetName() == aSearchName )
422             return sal_True;
423     }
424 
425     return sal_False;
426 }
427 
428 // XElementAccess
getElementType()429 uno::Type SAL_CALL SvxUnoMarkerTable::getElementType(  )
430 {
431     return ::getCppuType((const drawing::PointSequence*)0);
432 }
433 
hasElements()434 sal_Bool SAL_CALL SvxUnoMarkerTable::hasElements(  )
435 {
436     OGuard aGuard( Application::GetSolarMutex() );
437 
438     NameOrIndex *pItem;
439 
440     const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
441     sal_uInt32 nSurrogate;
442     for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
443     {
444         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate);
445         if( pItem && pItem->GetName().Len() != 0 )
446             return sal_True;
447     }
448 
449     const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
450     for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
451     {
452         pItem = (NameOrIndex*)mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate);
453         if( pItem && pItem->GetName().Len() != 0 )
454             return sal_True;
455     }
456 
457     return sal_False;
458 }
459 
460 /**
461  * Create a hatchtable
462  */
SvxUnoMarkerTable_createInstance(SdrModel * pModel)463 uno::Reference< uno::XInterface > SAL_CALL SvxUnoMarkerTable_createInstance( SdrModel* pModel )
464 {
465     return *new SvxUnoMarkerTable(pModel);
466 }
467