xref: /trunk/main/svx/source/unodraw/unomtabl.cxx (revision f6e50924)
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