xref: /trunk/main/svtools/source/uno/unoimap.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 #include <com/sun/star/container/XNameContainer.hpp>
31 #include <com/sun/star/container/XIndexContainer.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/document/XEventsSupplier.hpp>
34 #include <com/sun/star/lang/XUnoTunnel.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/awt/Rectangle.hpp>
37 #include <com/sun/star/awt/Point.hpp>
38 #include <com/sun/star/drawing/PointSequence.hpp>
39 #include <comphelper/servicehelper.hxx>
40 #include <comphelper/propertysethelper.hxx>
41 #include <comphelper/propertysetinfo.hxx>
42 #include <cppuhelper/weakagg.hxx>
43 #include <cppuhelper/implbase3.hxx>
44 #include <list>
45 #include <rtl/uuid.h>
46 #include <vos/mutex.hxx>
47 #include <vcl/svapp.hxx>
48 #include <svtools/unoevent.hxx>
49 #include <svtools/unoimap.hxx>
50 #include <svtools/imap.hxx>
51 #include <svtools/imapcirc.hxx>
52 #include <svtools/imaprect.hxx>
53 #include <svtools/imappoly.hxx>
54 
55 #ifndef SEQTYPE
56  #if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)
57   #define SEQTYPE(x) (new ::com::sun::star::uno::Type( x ))
58  #else
59   #define SEQTYPE(x) &(x)
60  #endif
61 #endif
62 
63 #define MAP_LEN(x) x, sizeof(x)-1
64 
65 
66 using namespace comphelper;
67 using namespace cppu;
68 using namespace com::sun::star;
69 using namespace com::sun::star::uno;
70 using namespace com::sun::star::lang;
71 using namespace com::sun::star::container;
72 using namespace com::sun::star::beans;
73 using namespace com::sun::star::document;
74 using namespace com::sun::star::drawing;
75 
76 const sal_Int32 HANDLE_URL = 1;
77 const sal_Int32 HANDLE_DESCRIPTION = 2;
78 const sal_Int32 HANDLE_TARGET = 3;
79 const sal_Int32 HANDLE_NAME = 4;
80 const sal_Int32 HANDLE_ISACTIVE = 5;
81 const sal_Int32 HANDLE_POLYGON = 6;
82 const sal_Int32 HANDLE_CENTER = 7;
83 const sal_Int32 HANDLE_RADIUS = 8;
84 const sal_Int32 HANDLE_BOUNDARY = 9;
85 const sal_Int32 HANDLE_TITLE = 10;
86 
87 class SvUnoImageMapObject : public OWeakAggObject,
88 							public XEventsSupplier,
89 							public XServiceInfo,
90 							public PropertySetHelper,
91 							public XTypeProvider,
92 							public XUnoTunnel
93 {
94 public:
95 	SvUnoImageMapObject( sal_uInt16 nType, const SvEventDescription* pSupportedMacroItems );
96 	SvUnoImageMapObject( const IMapObject& rMapObject, const SvEventDescription* pSupportedMacroItems );
97 	virtual ~SvUnoImageMapObject() throw();
98 
99 	UNO3_GETIMPLEMENTATION_DECL( SvUnoImageMapObject )
100 
101 	IMapObject* createIMapObject() const;
102 
103 	SvMacroTableEventDescriptor* mpEvents;
104 
105 	// overiden helpers from PropertySetHelper
106 	virtual void _setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues ) throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException );
107 	virtual void _getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValue ) throw(UnknownPropertyException, WrappedTargetException );
108 
109 	// XInterface
110 	virtual Any SAL_CALL queryAggregation( const Type & rType ) throw(RuntimeException);
111 	virtual Any SAL_CALL queryInterface( const Type & rType ) throw(RuntimeException);
112 	virtual void SAL_CALL acquire() throw();
113 	virtual void SAL_CALL release() throw();
114 
115 	// XTypeProvider
116     virtual Sequence< Type > SAL_CALL getTypes(  ) throw(RuntimeException);
117     virtual Sequence< sal_Int8 > SAL_CALL getImplementationId(  ) throw(RuntimeException);
118 
119     // XEventsSupplier
120     virtual Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents(  ) throw(RuntimeException);
121 
122     // XServiceInfo
123     virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw( RuntimeException );
124     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( RuntimeException );
125     virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw( RuntimeException );
126 
127 private:
128 	static PropertySetInfo* createPropertySetInfo( sal_uInt16 nType );
129 
130 
131 	sal_uInt16 mnType;
132 
133     ::rtl::OUString maURL;
134     ::rtl::OUString maAltText;
135     ::rtl::OUString maDesc;
136     ::rtl::OUString maTarget;
137     ::rtl::OUString maName;
138 	sal_Bool mbIsActive;
139 	awt::Rectangle maBoundary;
140 	awt::Point maCenter;
141 	sal_Int32 mnRadius;
142 	PointSequence maPolygon;
143 };
144 
145 UNO3_GETIMPLEMENTATION_IMPL( SvUnoImageMapObject );
146 
147 PropertySetInfo* SvUnoImageMapObject::createPropertySetInfo( sal_uInt16 nType )
148 {
149 	switch( nType )
150 	{
151 	case IMAP_OBJ_POLYGON:
152 		{
153 			static PropertyMapEntry aPolygonObj_Impl[] =
154 			{
155                 { MAP_LEN( "URL" ),         HANDLE_URL,         &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
156                 { MAP_LEN( "Title" ),       HANDLE_TITLE,       &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
157                 { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
158                 { MAP_LEN( "Target" ),      HANDLE_TARGET,      &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
159                 { MAP_LEN( "Name" ),        HANDLE_NAME,        &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
160 				{ MAP_LEN( "IsActive" ),	HANDLE_ISACTIVE,	&::getBooleanCppuType(),				0, 0 },
161 				{ MAP_LEN( "Polygon" ),		HANDLE_POLYGON,		SEQTYPE(::getCppuType((const PointSequence*)0)),	0, 0 },
162 				{0,0,0,0,0,0}
163 			};
164 
165 			return new PropertySetInfo( aPolygonObj_Impl );
166 		}
167 	case IMAP_OBJ_CIRCLE:
168 		{
169 			static PropertyMapEntry aCircleObj_Impl[] =
170 			{
171                 { MAP_LEN( "URL" ),         HANDLE_URL,         &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
172                 { MAP_LEN( "Title" ),       HANDLE_TITLE,       &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
173                 { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
174                 { MAP_LEN( "Target" ),      HANDLE_TARGET,      &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
175                 { MAP_LEN( "Name" ),            HANDLE_NAME,        &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
176 				{ MAP_LEN( "IsActive" ),		HANDLE_ISACTIVE,	&::getBooleanCppuType(),				0, 0 },
177 				{ MAP_LEN( "Center" ),		HANDLE_CENTER,		&::getCppuType((const awt::Point*)0),	0, 0 },
178 				{ MAP_LEN( "Radius" ),		HANDLE_RADIUS,		&::getCppuType((const sal_Int32*)0),	0, 0 },
179 				{0,0,0,0,0,0}
180 			};
181 
182 			return new PropertySetInfo( aCircleObj_Impl );
183 		}
184 	case IMAP_OBJ_RECTANGLE:
185 	default:
186 		{
187 			static PropertyMapEntry aRectangleObj_Impl[] =
188 			{
189                 { MAP_LEN( "URL" ),         HANDLE_URL,         &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
190                 { MAP_LEN( "Title" ),       HANDLE_TITLE,       &::getCppuType((const ::rtl::OUString*)0),     0, 0 },
191                 { MAP_LEN( "Description" ), HANDLE_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
192                 { MAP_LEN( "Target" ),      HANDLE_TARGET,      &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
193                 { MAP_LEN( "Name" ),        HANDLE_NAME,        &::getCppuType((const ::rtl::OUString*)0), 0, 0 },
194 				{ MAP_LEN( "IsActive" ),	HANDLE_ISACTIVE,	&::getBooleanCppuType(),			0, 0 },
195 				{ MAP_LEN( "Boundary" ),	HANDLE_BOUNDARY,	&::getCppuType((const awt::Rectangle*)0),	0, 0 },
196 				{0,0,0,0,0,0}
197 			};
198 
199 			return new PropertySetInfo( aRectangleObj_Impl );
200 		}
201 	}
202 }
203 
204 SvUnoImageMapObject::SvUnoImageMapObject( sal_uInt16 nType, const SvEventDescription* pSupportedMacroItems )
205 :	PropertySetHelper( createPropertySetInfo( nType ) ),
206 	mnType( nType )
207 ,   mbIsActive( true )
208 ,   mnRadius( 0 )
209 {
210 	mpEvents = new SvMacroTableEventDescriptor( pSupportedMacroItems );
211 	mpEvents->acquire();
212 }
213 
214 SvUnoImageMapObject::SvUnoImageMapObject( const IMapObject& rMapObject, const SvEventDescription* pSupportedMacroItems )
215 :	PropertySetHelper( createPropertySetInfo( rMapObject.GetType() ) ),
216 	mnType( rMapObject.GetType() )
217 ,   mbIsActive( true )
218 ,   mnRadius( 0 )
219 {
220 	maURL = rMapObject.GetURL();
221 	maAltText = rMapObject.GetAltText();
222 	maDesc = rMapObject.GetDesc();
223 	maTarget = rMapObject.GetTarget();
224 	maName = rMapObject.GetName();
225 	mbIsActive = rMapObject.IsActive();
226 
227 	switch( mnType )
228 	{
229 	case IMAP_OBJ_RECTANGLE:
230 		{
231 			const Rectangle aRect( ((IMapRectangleObject*)&rMapObject)->GetRectangle(sal_False) );
232 			maBoundary.X = aRect.Left();
233 			maBoundary.Y = aRect.Top();
234 			maBoundary.Width = aRect.GetWidth();
235 			maBoundary.Height = aRect.GetHeight();
236 		}
237 		break;
238 	case IMAP_OBJ_CIRCLE:
239 		{
240 			mnRadius = (sal_Int32)((IMapCircleObject*)&rMapObject)->GetRadius(sal_False);
241 			const Point aPoint( ((IMapCircleObject*)&rMapObject)->GetCenter(sal_False) );
242 
243 			maCenter.X = aPoint.X();
244 			maCenter.Y = aPoint.Y();
245 		}
246 		break;
247 	case IMAP_OBJ_POLYGON:
248     default:
249 		{
250 			const Polygon aPoly( ((IMapPolygonObject*)&rMapObject)->GetPolygon(sal_False) );
251 
252 			const sal_uInt16 nCount = aPoly.GetSize();
253 			maPolygon.realloc( nCount );
254 			awt::Point* pPoints = maPolygon.getArray();
255 
256 			for( sal_uInt16 nPoint = 0; nPoint < nCount; nPoint++ )
257 			{
258 				const Point& rPoint = aPoly.GetPoint( nPoint );
259 				pPoints->X = rPoint.X();
260 				pPoints->Y = rPoint.Y();
261 
262 				pPoints++;
263 			}
264 		}
265 	}
266 
267 	mpEvents = new SvMacroTableEventDescriptor( rMapObject.GetMacroTable(), pSupportedMacroItems );
268 	mpEvents->acquire();
269 }
270 
271 SvUnoImageMapObject::~SvUnoImageMapObject() throw()
272 {
273 	mpEvents->release();
274 }
275 
276 IMapObject* SvUnoImageMapObject::createIMapObject() const
277 {
278 	const String aURL( maURL );
279 	const String aAltText( maAltText );
280 	const String aDesc( maDesc );
281 	const String aTarget( maTarget );
282 	const String aName( maName );
283 
284 	IMapObject* pNewIMapObject;
285 
286 	switch( mnType )
287 	{
288 	case IMAP_OBJ_RECTANGLE:
289 		{
290 			const Rectangle aRect( maBoundary.X, maBoundary.Y, maBoundary.X + maBoundary.Width - 1, maBoundary.Y + maBoundary.Height - 1 );
291 			pNewIMapObject = new IMapRectangleObject( aRect, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False );
292 		}
293 		break;
294 
295 	case IMAP_OBJ_CIRCLE:
296 		{
297 			const Point aCenter( maCenter.X, maCenter.Y );
298 			pNewIMapObject = new IMapCircleObject( aCenter, mnRadius, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False );
299 		}
300 		break;
301 
302 	case IMAP_OBJ_POLYGON:
303 	default:
304 		{
305 			const sal_uInt16 nCount = (sal_uInt16)maPolygon.getLength();
306 
307 			Polygon aPoly( nCount );
308 			for( sal_uInt16 nPoint = 0; nPoint < nCount; nPoint++ )
309 			{
310 				Point aPoint( maPolygon[nPoint].X, maPolygon[nPoint].Y );
311 				aPoly.SetPoint( aPoint, nPoint );
312 			}
313 
314 			aPoly.Optimize( POLY_OPTIMIZE_CLOSE );
315 			pNewIMapObject = new IMapPolygonObject( aPoly, aURL, aAltText, aDesc, aTarget, aName, mbIsActive, sal_False );
316 		}
317 		break;
318 	}
319 
320 	SvxMacroTableDtor aMacroTable;
321 	mpEvents->copyMacrosIntoTable(aMacroTable);
322 	pNewIMapObject->SetMacroTable( aMacroTable );
323 
324 	return pNewIMapObject;
325 }
326 
327 // XInterface
328 
329 Any SAL_CALL SvUnoImageMapObject::queryInterface( const Type & rType )
330 	throw( RuntimeException )
331 {
332 	return OWeakAggObject::queryInterface( rType );
333 }
334 
335 Any SAL_CALL SvUnoImageMapObject::queryAggregation( const Type & rType )
336 	throw(RuntimeException)
337 {
338 	Any aAny;
339 
340 	if( rType == ::getCppuType((const Reference< XServiceInfo >*)0) )
341 		aAny <<= Reference< XServiceInfo >(this);
342 	else if( rType == ::getCppuType((const Reference< XTypeProvider >*)0) )
343 		aAny <<= Reference< XTypeProvider >(this);
344 	else if( rType == ::getCppuType((const Reference< XPropertySet >*)0) )
345 		aAny <<= Reference< XPropertySet >(this);
346 	else if( rType == ::getCppuType((const Reference< XEventsSupplier >*)0) )
347 		aAny <<= Reference< XEventsSupplier >(this);
348 	else if( rType == ::getCppuType((const Reference< XMultiPropertySet >*)0) )
349 		aAny <<= Reference< XMultiPropertySet >(this);
350 	else if( rType == ::getCppuType((const Reference< XUnoTunnel >*)0) )
351 		aAny <<= Reference< XUnoTunnel >(this);
352 	else
353 		aAny <<= OWeakAggObject::queryAggregation( rType );
354 
355 	return aAny;
356 }
357 
358 void SAL_CALL SvUnoImageMapObject::acquire() throw()
359 {
360 	OWeakAggObject::acquire();
361 }
362 
363 void SAL_CALL SvUnoImageMapObject::release() throw()
364 {
365 	OWeakAggObject::release();
366 }
367 
368 uno::Sequence< uno::Type > SAL_CALL SvUnoImageMapObject::getTypes()
369 	throw (uno::RuntimeException)
370 {
371 	uno::Sequence< uno::Type > aTypes( 7 );
372 	uno::Type* pTypes = aTypes.getArray();
373 
374 	*pTypes++ = ::getCppuType((const uno::Reference< XAggregation>*)0);
375 	*pTypes++ = ::getCppuType((const uno::Reference< XEventsSupplier>*)0);
376 	*pTypes++ = ::getCppuType((const uno::Reference< XServiceInfo>*)0);
377 	*pTypes++ = ::getCppuType((const uno::Reference< XPropertySet>*)0);
378 	*pTypes++ = ::getCppuType((const uno::Reference< XMultiPropertySet>*)0);
379 	*pTypes++ = ::getCppuType((const uno::Reference< XTypeProvider>*)0);
380 	*pTypes++ = ::getCppuType((const uno::Reference< XUnoTunnel>*)0);
381 
382 	return aTypes;
383 }
384 
385 uno::Sequence< sal_Int8 > SAL_CALL SvUnoImageMapObject::getImplementationId()
386 	throw (uno::RuntimeException)
387 {
388 	vos::OGuard aGuard( Application::GetSolarMutex() );
389 
390 	static uno::Sequence< sal_Int8 > aId;
391 	if( aId.getLength() == 0 )
392 	{
393 		aId.realloc( 16 );
394 		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
395 	}
396 	return aId;
397 }
398 
399 // XServiceInfo
400 
401 sal_Bool SAL_CALL SvUnoImageMapObject::supportsService( const  ::rtl::OUString& ServiceName ) throw(RuntimeException)
402 {
403     const Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
404     const ::rtl::OUString * pArray = aSNL.getConstArray();
405 
406 	const sal_Int32 nCount = aSNL.getLength();
407     for( sal_Int32 i = 0; i < nCount; i++ )
408         if( pArray[i] == ServiceName )
409             return sal_True;
410 
411     return sal_False;
412 }
413 
414 Sequence< ::rtl::OUString > SAL_CALL SvUnoImageMapObject::getSupportedServiceNames()
415 	throw(RuntimeException)
416 {
417     Sequence< ::rtl::OUString > aSNS( 2 );
418     aSNS.getArray()[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapObject" ));
419 	switch( mnType )
420 	{
421 	case IMAP_OBJ_POLYGON:
422     default:
423         aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapPolygonObject" ));
424 		break;
425 	case IMAP_OBJ_RECTANGLE:
426         aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapRectangleObject" ));
427 		break;
428 	case IMAP_OBJ_CIRCLE:
429         aSNS.getArray()[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.image.ImageMapCircleObject" ));
430 		break;
431 	}
432     return aSNS;
433 }
434 
435 ::rtl::OUString SAL_CALL SvUnoImageMapObject::getImplementationName() throw(RuntimeException)
436 {
437 	switch( mnType )
438 	{
439 	case IMAP_OBJ_POLYGON:
440 	default:
441         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapPolygonObject") );
442 	case IMAP_OBJ_CIRCLE:
443         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapCircleObject") );
444 	case IMAP_OBJ_RECTANGLE:
445         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.svt.ImageMapRectangleObject") );
446 	}
447 }
448 
449 // overiden helpers from PropertySetHelper
450 void SvUnoImageMapObject::_setPropertyValues( const PropertyMapEntry** ppEntries, const Any* pValues )
451 	throw(UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException )
452 {
453 	sal_Bool bOk = sal_False;
454 
455 	while( *ppEntries )
456 	{
457 		switch( (*ppEntries)->mnHandle )
458 		{
459 		case HANDLE_URL:
460 			bOk = *pValues >>= maURL;
461 			break;
462 		case HANDLE_TITLE:
463 			bOk = *pValues >>= maAltText;
464 			break;
465 		case HANDLE_DESCRIPTION:
466 			bOk = *pValues >>= maDesc;
467 			break;
468 		case HANDLE_TARGET:
469 			bOk = *pValues >>= maTarget;
470 			break;
471 		case HANDLE_NAME:
472 			bOk = *pValues >>= maName;
473 			break;
474 		case HANDLE_ISACTIVE:
475 			bOk = *pValues >>= mbIsActive;
476 			break;
477 		case HANDLE_BOUNDARY:
478 			bOk = *pValues >>= maBoundary;
479 			break;
480 		case HANDLE_CENTER:
481 			bOk = *pValues >>= maCenter;
482 			break;
483 		case HANDLE_RADIUS:
484 			bOk = *pValues >>= mnRadius;
485 			break;
486 		case HANDLE_POLYGON:
487 			bOk = *pValues >>= maPolygon;
488 			break;
489 		default:
490 			DBG_ERROR( "SvUnoImageMapObject::_setPropertyValues: unexpected property handle" );
491 			break;
492 		}
493 
494 		if( !bOk )
495 			throw IllegalArgumentException();
496 
497 		ppEntries++;
498 		pValues++;
499 	}
500 }
501 
502 void SvUnoImageMapObject::_getPropertyValues( const PropertyMapEntry** ppEntries, Any* pValues )
503 	throw(UnknownPropertyException, WrappedTargetException )
504 {
505 	while( *ppEntries )
506 	{
507 		switch( (*ppEntries)->mnHandle )
508 		{
509 		case HANDLE_URL:
510 			*pValues <<= maURL;
511 			break;
512 		case HANDLE_TITLE:
513 			*pValues <<= maAltText;
514 			break;
515 		case HANDLE_DESCRIPTION:
516 			*pValues <<= maDesc;
517 			break;
518 		case HANDLE_TARGET:
519 			*pValues <<= maTarget;
520 			break;
521 		case HANDLE_NAME:
522 			*pValues <<= maName;
523 			break;
524 		case HANDLE_ISACTIVE:
525 			*pValues <<= mbIsActive;
526 			break;
527 		case HANDLE_BOUNDARY:
528 			*pValues <<= maBoundary;
529 			break;
530 		case HANDLE_CENTER:
531 			*pValues <<= maCenter;
532 			break;
533 		case HANDLE_RADIUS:
534 			*pValues <<= mnRadius;
535 			break;
536 		case HANDLE_POLYGON:
537 			*pValues <<= maPolygon;
538 			break;
539 		default:
540 			DBG_ERROR( "SvUnoImageMapObject::_getPropertyValues: unexpected property handle" );
541 			break;
542 		}
543 
544 		ppEntries++;
545 		pValues++;
546 	}
547 }
548 
549 
550 Reference< XNameReplace > SAL_CALL SvUnoImageMapObject::getEvents()
551 	throw( RuntimeException )
552 {
553 	// try weak reference first
554 	Reference< XNameReplace > xEvents( mpEvents );
555 	return xEvents;
556 }
557 
558 ///////////////////////////////////////////////////////////////////////
559 
560 class SvUnoImageMap : public WeakImplHelper3< XIndexContainer, XServiceInfo, XUnoTunnel >
561 {
562 public:
563 	SvUnoImageMap( const SvEventDescription* pSupportedMacroItems );
564 	SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems );
565 	virtual ~SvUnoImageMap();
566 
567 	sal_Bool fillImageMap( ImageMap& rMap ) const;
568 	SvUnoImageMapObject* getObject( const Any& aElement ) const throw( IllegalArgumentException );
569 
570 	UNO3_GETIMPLEMENTATION_DECL( SvUnoImageMap )
571 
572 	// XIndexContainer
573     virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element ) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
574     virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
575 
576     // XIndexReplace
577     virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element ) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
578 
579     // XIndexAccess
580     virtual sal_Int32 SAL_CALL getCount(  ) throw( RuntimeException );
581     virtual Any SAL_CALL getByIndex( sal_Int32 Index ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
582 
583     // XElementAccess
584     virtual Type SAL_CALL getElementType(  ) throw( RuntimeException );
585     virtual sal_Bool SAL_CALL hasElements(  ) throw( RuntimeException );
586 
587     // XSerivceInfo
588     virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw( RuntimeException );
589     virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw( RuntimeException );
590     virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw( RuntimeException );
591 
592 private:
593     ::rtl::OUString maName;
594 
595 	std::list< SvUnoImageMapObject* > maObjectList;
596 };
597 
598 UNO3_GETIMPLEMENTATION_IMPL( SvUnoImageMap );
599 
600 SvUnoImageMap::SvUnoImageMap( const SvEventDescription* )
601 {
602 }
603 
604 SvUnoImageMap::SvUnoImageMap( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems )
605 {
606 	maName = rMap.GetName();
607 
608 	const sal_uInt16 nCount = rMap.GetIMapObjectCount();
609 	for( sal_uInt16 nPos = 0; nPos < nCount; nPos++ )
610 	{
611 		IMapObject* pMapObject = rMap.GetIMapObject( nPos );
612 		SvUnoImageMapObject* pUnoObj = new SvUnoImageMapObject( *pMapObject, pSupportedMacroItems );
613 		pUnoObj->acquire();
614 		maObjectList.push_back( pUnoObj );
615 	}
616 }
617 
618 SvUnoImageMap::~SvUnoImageMap()
619 {
620 	std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
621 	const std::list< SvUnoImageMapObject* >::iterator aEnd = maObjectList.end();
622 	while( aIter != aEnd )
623 	{
624 		(*aIter++)->release();
625 	}
626 }
627 
628 SvUnoImageMapObject* SvUnoImageMap::getObject( const Any& aElement ) const
629 	throw( IllegalArgumentException )
630 {
631 	Reference< XInterface > xObject;
632 	aElement >>= xObject;
633 
634 	SvUnoImageMapObject* pObject = SvUnoImageMapObject::getImplementation( xObject );
635 	if( NULL == pObject )
636 		throw IllegalArgumentException();
637 
638 	return pObject;
639 }
640 
641 // XIndexContainer
642 void SAL_CALL SvUnoImageMap::insertByIndex( sal_Int32 Index, const Any& Element )
643 	throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
644 {
645 	SvUnoImageMapObject* pObject = getObject( Element );
646 	const sal_Int32 nCount = maObjectList.size();
647 	if( NULL == pObject || Index > nCount )
648 		throw IndexOutOfBoundsException();
649 
650 	pObject->acquire();
651 
652 	if( Index == nCount )
653 		maObjectList.push_back( pObject );
654 	else
655 	{
656 		std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
657 		for( sal_Int32 n = 0; n < Index; n++ )
658 			aIter++;
659 
660 		maObjectList.insert( aIter, pObject );
661 	}
662 }
663 
664 void SAL_CALL SvUnoImageMap::removeByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
665 {
666 	const sal_Int32 nCount = maObjectList.size();
667 	if( Index >= nCount )
668 		throw IndexOutOfBoundsException();
669 
670 	if( nCount - 1 == Index )
671 	{
672 		maObjectList.back()->release();
673 		maObjectList.pop_back();
674 	}
675 	else
676 	{
677 		std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
678 		for( sal_Int32 n = 0; n < Index; n++ )
679 			aIter++;
680 
681 		(*aIter)->release();
682 		maObjectList.erase( aIter );
683 	}
684 }
685 
686 // XIndexReplace
687 void SAL_CALL SvUnoImageMap::replaceByIndex( sal_Int32 Index, const Any& Element ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
688 {
689 	SvUnoImageMapObject* pObject = getObject( Element );
690 	const sal_Int32 nCount = maObjectList.size();
691 	if( NULL == pObject || Index >= nCount )
692 		throw IndexOutOfBoundsException();
693 
694 	std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
695 	for( sal_Int32 n = 0; n < Index; n++ )
696 		aIter++;
697 
698 	(*aIter)->release();
699 	*aIter = pObject;
700 	pObject->acquire();
701 }
702 
703 // XIndexAccess
704 sal_Int32 SAL_CALL SvUnoImageMap::getCount(  ) throw(RuntimeException)
705 {
706 	return maObjectList.size();
707 }
708 
709 Any SAL_CALL SvUnoImageMap::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
710 {
711 	const sal_Int32 nCount = maObjectList.size();
712 	if( Index >= nCount )
713 		throw IndexOutOfBoundsException();
714 
715 	std::list< SvUnoImageMapObject* >::iterator aIter = maObjectList.begin();
716 	for( sal_Int32 n = 0; n < Index; n++ )
717 		aIter++;
718 
719 	Reference< XPropertySet > xObj( *aIter );
720 	return makeAny( xObj );
721 }
722 
723 // XElementAccess
724 Type SAL_CALL SvUnoImageMap::getElementType(  ) throw(RuntimeException)
725 {
726 	return ::getCppuType((const Reference< XPropertySet >*)0);
727 }
728 
729 sal_Bool SAL_CALL SvUnoImageMap::hasElements(  ) throw(RuntimeException)
730 {
731 	return maObjectList.size() != 0;
732 }
733 
734 // XSerivceInfo
735 ::rtl::OUString SAL_CALL SvUnoImageMap::getImplementationName(  )
736 	throw(RuntimeException)
737 {
738     return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.svt.SvUnoImageMap" ) );
739 }
740 
741 sal_Bool SAL_CALL SvUnoImageMap::supportsService( const ::rtl::OUString& ServiceName )
742 	throw(RuntimeException)
743 {
744     const Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() );
745     const ::rtl::OUString * pArray = aSNL.getConstArray();
746 
747 	const sal_Int32 nCount = aSNL.getLength();
748     for( sal_Int32 i = 0; i < nCount; i++ )
749         if( pArray[i] == ServiceName )
750             return sal_True;
751 
752     return sal_False;
753 }
754 
755 Sequence< ::rtl::OUString > SAL_CALL SvUnoImageMap::getSupportedServiceNames(  )
756 	throw(RuntimeException)
757 {
758     const ::rtl::OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.image.ImageMap" ) );
759     return Sequence< ::rtl::OUString >( &aSN, 1 );
760 }
761 
762 sal_Bool SvUnoImageMap::fillImageMap( ImageMap& rMap ) const
763 {
764 	rMap.ClearImageMap();
765 
766 	rMap.SetName( maName );
767 
768 	std::list< SvUnoImageMapObject* >::const_iterator aIter = maObjectList.begin();
769 	const std::list< SvUnoImageMapObject* >::const_iterator aEnd = maObjectList.end();
770 	while( aIter != aEnd )
771 	{
772 		IMapObject* pNewMapObject = (*aIter)->createIMapObject();
773 		rMap.InsertIMapObject( *pNewMapObject );
774 		delete pNewMapObject;
775 
776 		aIter++;
777 	}
778 
779 	return sal_True;
780 }
781 
782 // -------------------------------------------------------------------
783 // factory helper methods
784 // -------------------------------------------------------------------
785 
786 Reference< XInterface > SvUnoImageMapRectangleObject_createInstance( const SvEventDescription* pSupportedMacroItems )
787 {
788 	return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_RECTANGLE, pSupportedMacroItems );
789 }
790 
791 Reference< XInterface > SvUnoImageMapCircleObject_createInstance( const SvEventDescription* pSupportedMacroItems )
792 {
793 	return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_CIRCLE, pSupportedMacroItems );
794 }
795 
796 Reference< XInterface > SvUnoImageMapPolygonObject_createInstance( const SvEventDescription* pSupportedMacroItems )
797 {
798 	return (XWeak*)new SvUnoImageMapObject( IMAP_OBJ_POLYGON, pSupportedMacroItems );
799 }
800 
801 Reference< XInterface > SvUnoImageMap_createInstance( const SvEventDescription* pSupportedMacroItems )
802 {
803 	return (XWeak*)new SvUnoImageMap( pSupportedMacroItems );
804 }
805 
806 Reference< XInterface > SvUnoImageMap_createInstance( const ImageMap& rMap, const SvEventDescription* pSupportedMacroItems )
807 {
808 	return (XWeak*)new SvUnoImageMap( rMap, pSupportedMacroItems );
809 }
810 
811 sal_Bool SvUnoImageMap_fillImageMap( Reference< XInterface > xImageMap, ImageMap& rMap )
812 {
813 	SvUnoImageMap* pUnoImageMap = SvUnoImageMap::getImplementation( xImageMap );
814 	if( NULL == pUnoImageMap )
815 		return sal_False;
816 
817 	return pUnoImageMap->fillImageMap( rMap );
818 }
819