xref: /trunk/main/svtools/source/uno/unoimap.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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