xref: /trunk/main/svx/source/unodraw/unoshap2.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_svx.hxx"
30 
31 #define _SVX_USE_UNOGLOBALS_
32 #include <com/sun/star/lang/DisposedException.hpp>
33 #include <com/sun/star/awt/FontSlant.hpp>
34 #include <com/sun/star/style/VerticalAlignment.hpp>
35 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
36 #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
37 #include <com/sun/star/awt/TextAlign.hpp>  //added by BerryJia for fixing Bug102407 2002-11-4
38 #include <com/sun/star/style/ParagraphAdjust.hpp>   //added by BerryJia for fixing Bug102407 2002-11-4
39 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
40 #include <com/sun/star/drawing/PointSequence.hpp>
41 #include <com/sun/star/graphic/XGraphic.hpp>
42 #include <tools/urlobj.hxx>
43 #include <unotools/localfilehelper.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vos/mutex.hxx>
46 #include <svtools/fltcall.hxx>
47 #include <svtools/filter.hxx>
48 
49 #include <boost/scoped_ptr.hpp>
50 #include <svx/svdpool.hxx>
51 #include <rtl/uuid.h>
52 #include <rtl/memory.h>
53 #include <tools/urlobj.hxx>
54 
55 #include <editeng/unoprnms.hxx>
56 #include <svx/unoshape.hxx>
57 #include <svx/unopage.hxx>
58 #include <svx/svdobj.hxx>
59 #include <svx/svdpage.hxx>
60 #include <svx/svdmodel.hxx>
61 #include <svx/svdouno.hxx>
62 #include "shapeimpl.hxx"
63 #include "svx/unoshprp.hxx"
64 #include <svx/svdoashp.hxx>
65 #include "unopolyhelper.hxx"
66 
67 // #i29181#
68 #include "svx/svdviter.hxx"
69 #include <svx/svdview.hxx>
70 #include <basegfx/matrix/b2dhommatrix.hxx>
71 #include <basegfx/polygon/b2dpolygon.hxx>
72 #include <basegfx/point/b2dpoint.hxx>
73 #include <basegfx/polygon/b2dpolygontools.hxx>
74 
75 using ::rtl::OUString;
76 using namespace ::osl;
77 using namespace ::vos;
78 using namespace ::cppu;
79 using namespace ::com::sun::star;
80 using namespace ::com::sun::star::uno;
81 using namespace ::com::sun::star::lang;
82 using namespace ::com::sun::star::container;
83 
84 #define INTERFACE_TYPE( xint ) \
85     ::getCppuType((const Reference< xint >*)0)
86 
87 #define QUERYINT( xint ) \
88     if( rType == ::getCppuType((const Reference< xint >*)0) ) \
89         aAny <<= Reference< xint >(this)
90 
91 class GDIMetaFile;
92 class SvStream;
93 sal_Bool ConvertGDIMetaFileToWMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
94                               FilterConfigItem* pFilterConfigItem = NULL, sal_Bool bPlaceable = sal_True );
95 
96 /***********************************************************************
97 * class SvxShapeGroup                                                  *
98 ***********************************************************************/
99 
100 SvxShapeGroup::SvxShapeGroup( SdrObject* pObj, SvxDrawPage* pDrawPage  )  throw() :
101     SvxShape( pObj, aSvxMapProvider.GetMap(SVXMAP_GROUP), aSvxMapProvider.GetPropertySet(SVXMAP_GROUP, SdrObject::GetGlobalDrawObjectItemPool()) ),
102     mxPage( pDrawPage )
103 {
104 }
105 
106 //----------------------------------------------------------------------
107 SvxShapeGroup::~SvxShapeGroup() throw()
108 {
109 }
110 
111 //----------------------------------------------------------------------
112 void SvxShapeGroup::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
113 {
114     SvxShape::Create( pNewObj, pNewPage );
115     mxPage = pNewPage;
116 }
117 
118 //----------------------------------------------------------------------
119 uno::Any SAL_CALL SvxShapeGroup::queryInterface( const uno::Type & rType )
120     throw(uno::RuntimeException)
121 {
122     return SvxShape::queryInterface( rType );
123 }
124 
125 uno::Any SAL_CALL SvxShapeGroup::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException)
126 {
127     uno::Any aAny;
128 
129     QUERYINT( drawing::XShapeGroup );
130     else QUERYINT( drawing::XShapes );
131     else QUERYINT( container::XIndexAccess );
132     else QUERYINT( container::XElementAccess );
133     else
134         return SvxShape::queryAggregation( rType );
135 
136     return aAny;
137 }
138 
139 void SAL_CALL SvxShapeGroup::acquire() throw ( )
140 {
141     SvxShape::acquire();
142 }
143 
144 void SAL_CALL SvxShapeGroup::release() throw ( )
145 {
146     SvxShape::release();
147 }
148 
149 uno::Sequence< uno::Type > SAL_CALL SvxShapeGroup::getTypes()
150     throw (uno::RuntimeException)
151 {
152     return SvxShape::getTypes();
153 }
154 
155 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeGroup::getImplementationId()
156     throw (uno::RuntimeException)
157 {
158     static uno::Sequence< sal_Int8 > aId;
159     if( aId.getLength() == 0 )
160     {
161         aId.realloc( 16 );
162         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
163     }
164     return aId;
165 }
166 
167 // ::com::sun::star::drawing::XShape
168 
169 //----------------------------------------------------------------------
170 OUString SAL_CALL SvxShapeGroup::getShapeType()
171     throw( uno::RuntimeException )
172 {
173     return SvxShape::getShapeType();
174 }
175 
176 //------------------------------------------------------------------1----
177 awt::Point SAL_CALL SvxShapeGroup::getPosition() throw(uno::RuntimeException)
178 {
179     return SvxShape::getPosition();
180 }
181 
182 //----------------------------------------------------------------------
183 void SAL_CALL SvxShapeGroup::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
184 {
185     SvxShape::setPosition(Position);
186 }
187 
188 //----------------------------------------------------------------------
189 
190 awt::Size SAL_CALL SvxShapeGroup::getSize() throw(uno::RuntimeException)
191 {
192     return SvxShape::getSize();
193 }
194 
195 //----------------------------------------------------------------------
196 void SAL_CALL SvxShapeGroup::setSize( const awt::Size& rSize )
197     throw(beans::PropertyVetoException, uno::RuntimeException)
198 {
199     SvxShape::setSize( rSize );
200 }
201 
202 // drawing::XShapeGroup
203 
204 //----------------------------------------------------------------------
205 void SAL_CALL SvxShapeGroup::enterGroup(  ) throw(uno::RuntimeException)
206 {
207     // Todo
208 //  pDrView->EnterMarkedGroup();
209 }
210 
211 //----------------------------------------------------------------------
212 void SAL_CALL SvxShapeGroup::leaveGroup(  ) throw(uno::RuntimeException)
213 {
214     // Todo
215 //  pDrView->LeaveOneGroup();
216 }
217 
218 //----------------------------------------------------------------------
219 
220 // XShapes
221 void SAL_CALL SvxShapeGroup::add( const uno::Reference< drawing::XShape >& xShape )
222     throw( uno::RuntimeException )
223 {
224     OGuard aGuard( Application::GetSolarMutex() );
225 
226     SvxShape* pShape = SvxShape::getImplementation( xShape );
227 
228     if( mpObj.is()&& mxPage.is() && pShape )
229     {
230         SdrObject* pSdrShape = pShape->GetSdrObject();
231         if( pSdrShape == NULL )
232             pSdrShape = mxPage->_CreateSdrObject( xShape );
233 
234         if( pSdrShape->IsInserted() )
235             pSdrShape->GetObjList()->RemoveObject( pSdrShape->GetOrdNum() );
236 
237         mpObj->GetSubList()->InsertObject( pSdrShape );
238         pSdrShape->SetModel(mpObj->GetModel());
239 
240         // #85922# It makes no sense to set the layer asked
241         // from the group object since these is an iteration
242         // over the contained objects. In consequence, this
243         // statement erases all layer information from the draw
244         // objects. Layers need to be set at draw objects directly
245         // and have nothing to do with grouping at all.
246         // pSdrShape->SetLayer(pObject->GetLayer());
247 
248         // Establish connection between new SdrObject and its wrapper before
249         // inserting the new shape into the group.  There a new wrapper
250         // would be created when this connection would not already exist.
251         if(pShape)
252             pShape->Create( pSdrShape, mxPage.get() );
253 
254         if( mpModel )
255             mpModel->SetChanged();
256     }
257     else
258     {
259         DBG_ERROR("could not add XShape to group shape!");
260     }
261 }
262 
263 //----------------------------------------------------------------------
264 void SAL_CALL SvxShapeGroup::remove( const uno::Reference< drawing::XShape >& xShape )
265     throw( uno::RuntimeException )
266 {
267     OGuard aGuard( Application::GetSolarMutex() );
268 
269     SdrObject* pSdrShape = NULL;
270     SvxShape* pShape = SvxShape::getImplementation( xShape );
271 
272     if( pShape )
273         pSdrShape = pShape->GetSdrObject();
274 
275     if( !mpObj.is() || pSdrShape == NULL || pSdrShape->GetObjList()->GetOwnerObj() != mpObj.get() )
276         throw uno::RuntimeException();
277 
278     SdrObjList& rList = *pSdrShape->GetObjList();
279 
280     const sal_uInt32 nObjCount = rList.GetObjCount();
281     sal_uInt32 nObjNum = 0;
282     while( nObjNum < nObjCount )
283     {
284         if(rList.GetObj( nObjNum ) == pSdrShape )
285             break;
286         nObjNum++;
287     }
288 
289     if( nObjNum < nObjCount )
290     {
291         // #i29181#
292         // If the SdrObject which is about to be deleted is in any selection,
293         // deselect it first.
294         SdrViewIter aIter( pSdrShape );
295 
296         for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
297         {
298             if(CONTAINER_ENTRY_NOTFOUND != pView->TryToFindMarkedObject(pSdrShape))
299             {
300                 pView->MarkObj(pSdrShape, pView->GetSdrPageView(), sal_True, sal_False);
301             }
302         }
303 
304         SdrObject* pObject = rList.NbcRemoveObject( nObjNum );
305         SdrObject::Free( pObject );
306     }
307     else
308     {
309         DBG_ASSERT( 0, "Fatality! SdrObject is not belonging to its SdrObjList! [CL]" );
310     }
311 
312     if( mpModel )
313         mpModel->SetChanged();
314 }
315 
316 // XIndexAccess
317 
318 //----------------------------------------------------------------------
319 sal_Int32 SAL_CALL SvxShapeGroup::getCount() throw( uno::RuntimeException )
320 {
321     OGuard aGuard( Application::GetSolarMutex() );
322 
323     sal_Int32 nRetval = 0;
324 
325     if(mpObj.is() && mpObj->GetSubList())
326         nRetval = mpObj->GetSubList()->GetObjCount();
327     else
328         throw uno::RuntimeException();
329 
330     return nRetval;
331 }
332 
333 //----------------------------------------------------------------------
334 uno::Any SAL_CALL SvxShapeGroup::getByIndex( sal_Int32 Index )
335     throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
336 {
337     OGuard aGuard( Application::GetSolarMutex() );
338 
339     if( !mpObj.is() || mpObj->GetSubList() == NULL )
340         throw uno::RuntimeException();
341 
342     if( mpObj->GetSubList()->GetObjCount() <= (sal_uInt32)Index )
343         throw lang::IndexOutOfBoundsException();
344 
345     SdrObject* pDestObj = mpObj->GetSubList()->GetObj( Index );
346 
347     if(pDestObj == NULL)
348         throw lang::IndexOutOfBoundsException();
349 
350     Reference< drawing::XShape > xShape( pDestObj->getUnoShape(), uno::UNO_QUERY );
351     return uno::makeAny( xShape );
352 }
353 
354 // ::com::sun::star::container::XElementAccess
355 
356 //----------------------------------------------------------------------
357 uno::Type SAL_CALL SvxShapeGroup::getElementType() throw( uno::RuntimeException )
358 {
359     return ::getCppuType(( const Reference< drawing::XShape >*)0);
360 }
361 
362 //----------------------------------------------------------------------
363 sal_Bool SAL_CALL SvxShapeGroup::hasElements() throw( uno::RuntimeException )
364 {
365     OGuard aGuard( Application::GetSolarMutex() );
366 
367     return mpObj.is() && mpObj->GetSubList() && (mpObj->GetSubList()->GetObjCount() > 0);
368 }
369 
370 //----------------------------------------------------------------------
371 // ::com::sun::star::lang::XServiceInfo
372 
373 uno::Sequence< OUString > SAL_CALL SvxShapeGroup::getSupportedServiceNames()
374     throw(uno::RuntimeException)
375 {
376     return SvxShape::getSupportedServiceNames();
377 }
378 
379 /***********************************************************************
380 *                                                                      *
381 ***********************************************************************/
382 
383 SvxShapeConnector::SvxShapeConnector( SdrObject* pObj )  throw() :
384     SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CONNECTOR), aSvxMapProvider.GetPropertySet(SVXMAP_CONNECTOR, SdrObject::GetGlobalDrawObjectItemPool()) )
385 {
386 }
387 
388 //----------------------------------------------------------------------
389 SvxShapeConnector::~SvxShapeConnector() throw()
390 {
391 }
392 
393 //----------------------------------------------------------------------
394 
395 uno::Any SAL_CALL SvxShapeConnector::queryInterface( const uno::Type & rType )
396     throw(uno::RuntimeException)
397 {
398     return SvxShapeText::queryInterface( rType );
399 }
400 
401 uno::Any SAL_CALL SvxShapeConnector::queryAggregation( const uno::Type & rType )
402     throw(uno::RuntimeException)
403 {
404     uno::Any aAny;
405 
406     QUERYINT( drawing::XConnectorShape );
407     else
408         return SvxShapeText::queryAggregation( rType );
409 
410     return aAny;
411 }
412 
413 void SAL_CALL SvxShapeConnector::acquire() throw ( )
414 {
415     SvxShapeText::acquire();
416 }
417 
418 void SAL_CALL SvxShapeConnector::release() throw ( )
419 {
420     SvxShapeText::release();
421 }
422 // XTypeProvider
423 
424 uno::Sequence< uno::Type > SAL_CALL SvxShapeConnector::getTypes()
425     throw (uno::RuntimeException)
426 {
427     return SvxShape::getTypes();
428 }
429 
430 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeConnector::getImplementationId()
431     throw (uno::RuntimeException)
432 {
433     static uno::Sequence< sal_Int8 > aId;
434     if( aId.getLength() == 0 )
435     {
436         aId.realloc( 16 );
437         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
438     }
439     return aId;
440 }
441 
442 // ::com::sun::star::drawing::XShape
443 
444 //----------------------------------------------------------------------
445 OUString SAL_CALL SvxShapeConnector::getShapeType()
446     throw( uno::RuntimeException )
447 {
448     return SvxShapeText::getShapeType();
449 }
450 
451 //------------------------------------------------------------------1----
452 awt::Point SAL_CALL SvxShapeConnector::getPosition() throw(uno::RuntimeException)
453 {
454     return SvxShapeText::getPosition();
455 }
456 
457 //----------------------------------------------------------------------
458 void SAL_CALL SvxShapeConnector::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
459 {
460     SvxShapeText::setPosition(Position);
461 }
462 
463 //----------------------------------------------------------------------
464 
465 awt::Size SAL_CALL SvxShapeConnector::getSize() throw(uno::RuntimeException)
466 {
467     return SvxShapeText::getSize();
468 }
469 
470 //----------------------------------------------------------------------
471 void SAL_CALL SvxShapeConnector::setSize( const awt::Size& rSize )
472     throw(beans::PropertyVetoException, uno::RuntimeException)
473 {
474     SvxShapeText::setSize( rSize );
475 }
476 
477 //----------------------------------------------------------------------
478 
479 // XConnectorShape
480 
481 void SAL_CALL SvxShapeConnector::connectStart( const uno::Reference< drawing::XConnectableShape >& xShape, drawing::ConnectionType ) throw( uno::RuntimeException )
482 {
483     OGuard aGuard( Application::GetSolarMutex() );
484 
485     Reference< drawing::XShape > xRef( xShape, UNO_QUERY );
486     SvxShape* pShape = SvxShape::getImplementation( xRef );
487 
488     if( pShape )
489         mpObj->ConnectToNode( sal_True, pShape->mpObj.get() );
490 
491     if( mpModel )
492         mpModel->SetChanged();
493 }
494 
495 //----------------------------------------------------------------------
496 void SAL_CALL SvxShapeConnector::connectEnd( const uno::Reference< drawing::XConnectableShape >& xShape, drawing::ConnectionType  )
497     throw( uno::RuntimeException )
498 {
499     OGuard aGuard( Application::GetSolarMutex() );
500 
501     Reference< drawing::XShape > xRef( xShape, UNO_QUERY );
502     SvxShape* pShape = SvxShape::getImplementation( xRef );
503 
504     if( mpObj.is() && pShape )
505         mpObj->ConnectToNode( sal_False, pShape->mpObj.get() );
506 
507     if( mpModel )
508         mpModel->SetChanged();
509 }
510 
511 //----------------------------------------------------------------------
512 void SAL_CALL SvxShapeConnector::disconnectBegin( const uno::Reference< drawing::XConnectableShape >&  )
513     throw( uno::RuntimeException )
514 {
515     OGuard aGuard( Application::GetSolarMutex() );
516 
517     if(mpObj.is())
518         mpObj->DisconnectFromNode( sal_True );
519 
520     if( mpModel )
521         mpModel->SetChanged();
522 }
523 
524 //----------------------------------------------------------------------
525 void SAL_CALL SvxShapeConnector::disconnectEnd( const uno::Reference< drawing::XConnectableShape >& )
526     throw( uno::RuntimeException )
527 {
528     OGuard aGuard( Application::GetSolarMutex() );
529 
530     if(mpObj.is())
531         mpObj->DisconnectFromNode( sal_False );
532 
533     if( mpModel )
534         mpModel->SetChanged();
535 }
536 
537 //----------------------------------------------------------------------
538 // ::com::sun::star::lang::XServiceInfo
539 //----------------------------------------------------------------------
540 uno::Sequence< OUString > SAL_CALL SvxShapeConnector::getSupportedServiceNames() throw( uno::RuntimeException )
541 {
542     return SvxShapeText::getSupportedServiceNames();
543 }
544 
545 /***********************************************************************
546 * class SvxShapeControl                                                *
547 ***********************************************************************/
548 DBG_NAME(SvxShapeControl)
549 
550 SvxShapeControl::SvxShapeControl( SdrObject* pObj )  throw() :
551     SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CONTROL), aSvxMapProvider.GetPropertySet(SVXMAP_CONTROL, SdrObject::GetGlobalDrawObjectItemPool()) )
552 {
553     DBG_CTOR(SvxShapeControl,NULL);
554     setShapeKind( OBJ_UNO );
555 }
556 
557 //----------------------------------------------------------------------
558 SvxShapeControl::~SvxShapeControl() throw()
559 {
560     DBG_DTOR(SvxShapeControl,NULL);
561 }
562 
563 //----------------------------------------------------------------------
564 uno::Any SAL_CALL SvxShapeControl::queryInterface( const uno::Type & rType )
565     throw(uno::RuntimeException)
566 {
567     return SvxShapeText::queryInterface( rType );
568 }
569 
570 uno::Any SAL_CALL SvxShapeControl::queryAggregation( const uno::Type & rType ) throw(uno::RuntimeException)
571 {
572     uno::Any aAny;
573 
574     QUERYINT( drawing::XControlShape );
575     else
576         return SvxShapeText::queryAggregation( rType );
577 
578     return aAny;
579 }
580 
581 void SAL_CALL SvxShapeControl::acquire() throw ( )
582 {
583     SvxShapeText::acquire();
584 }
585 
586 void SAL_CALL SvxShapeControl::release() throw ( )
587 {
588     SvxShapeText::release();
589 }
590 // XTypeProvider
591 
592 uno::Sequence< uno::Type > SAL_CALL SvxShapeControl::getTypes()
593     throw (uno::RuntimeException)
594 {
595     return SvxShape::getTypes();
596 }
597 
598 uno::Sequence< sal_Int8 > SAL_CALL SvxShapeControl::getImplementationId()
599     throw (uno::RuntimeException)
600 {
601     static uno::Sequence< sal_Int8 > aId;
602     if( aId.getLength() == 0 )
603     {
604         aId.realloc( 16 );
605         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
606     }
607     return aId;
608 }
609 
610 // ::com::sun::star::drawing::XShape
611 
612 //----------------------------------------------------------------------
613 OUString SAL_CALL SvxShapeControl::getShapeType()
614     throw( uno::RuntimeException )
615 {
616     return SvxShapeText::getShapeType();
617 }
618 
619 //------------------------------------------------------------------1----
620 awt::Point SAL_CALL SvxShapeControl::getPosition() throw(uno::RuntimeException)
621 {
622     return SvxShapeText::getPosition();
623 }
624 
625 //----------------------------------------------------------------------
626 void SAL_CALL SvxShapeControl::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
627 {
628     SvxShapeText::setPosition(Position);
629 }
630 
631 //----------------------------------------------------------------------
632 
633 awt::Size SAL_CALL SvxShapeControl::getSize() throw(uno::RuntimeException)
634 {
635     return SvxShapeText::getSize();
636 }
637 
638 //----------------------------------------------------------------------
639 void SAL_CALL SvxShapeControl::setSize( const awt::Size& rSize )
640     throw(beans::PropertyVetoException, uno::RuntimeException)
641 {
642     SvxShapeText::setSize( rSize );
643 }
644 
645 //----------------------------------------------------------------------
646 // XControlShape
647 
648 Reference< awt::XControlModel > SAL_CALL SvxShapeControl::getControl()
649     throw( uno::RuntimeException )
650 {
651     OGuard aGuard( Application::GetSolarMutex() );
652 
653     Reference< awt::XControlModel > xModel;
654 
655     SdrUnoObj* pUnoObj = dynamic_cast< SdrUnoObj * >(mpObj.get());
656     if( pUnoObj )
657         xModel = pUnoObj->GetUnoControlModel();
658 
659     return xModel;
660 }
661 
662 //----------------------------------------------------------------------
663 void SAL_CALL SvxShapeControl::setControl( const Reference< awt::XControlModel >& xControl )
664     throw( uno::RuntimeException )
665 {
666     OGuard aGuard( Application::GetSolarMutex() );
667 
668     SdrUnoObj* pUnoObj = dynamic_cast< SdrUnoObj * >(mpObj.get());
669     if( pUnoObj )
670         pUnoObj->SetUnoControlModel( xControl );
671 
672     if( mpModel )
673         mpModel->SetChanged();
674 }
675 
676 // XServiceInfo
677 uno::Sequence< OUString > SAL_CALL SvxShapeControl::getSupportedServiceNames() throw( uno::RuntimeException )
678 {
679     return SvxShapeText::getSupportedServiceNames();
680 }
681 
682 static struct
683 {
684     const sal_Char* mpAPIName;
685     sal_uInt16 mnAPINameLen;
686 
687     const sal_Char* mpFormName;
688     sal_uInt16 mnFormNameLen;
689 }
690 SvxShapeControlPropertyMapping[] =
691 {
692     // Warning: The first entry must be FontSlant because the any needs to be converted
693     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_POSTURE), MAP_CHAR_LEN("FontSlant")  }, //  const sal_Int16 => ::com::sun::star::awt::FontSlant
694     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTNAME), MAP_CHAR_LEN("FontName") },
695     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTSTYLENAME), MAP_CHAR_LEN("FontStyleName") },
696     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTFAMILY), MAP_CHAR_LEN("FontFamily") },
697     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTCHARSET), MAP_CHAR_LEN("FontCharset") },
698     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_HEIGHT), MAP_CHAR_LEN("FontHeight") },
699     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_FONTPITCH), MAP_CHAR_LEN("FontPitch" ) },
700     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_WEIGHT), MAP_CHAR_LEN("FontWeight" ) },
701     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_UNDERLINE), MAP_CHAR_LEN("FontUnderline") },
702     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_STRIKEOUT), MAP_CHAR_LEN("FontStrikeout") },
703     { MAP_CHAR_LEN("CharKerning"), MAP_CHAR_LEN("FontKerning") },
704     { MAP_CHAR_LEN("CharWordMode"), MAP_CHAR_LEN("FontWordLineMode" ) },
705     { MAP_CHAR_LEN(UNO_NAME_EDIT_CHAR_COLOR),   MAP_CHAR_LEN("TextColor") },
706     { MAP_CHAR_LEN("CharRelief"),   MAP_CHAR_LEN("FontRelief") },
707     { MAP_CHAR_LEN("CharUnderlineColor"),   MAP_CHAR_LEN("TextLineColor") },
708     { MAP_CHAR_LEN(UNO_NAME_EDIT_PARA_ADJUST), MAP_CHAR_LEN("Align") },
709     { MAP_CHAR_LEN("TextVerticalAdjust"), MAP_CHAR_LEN("VerticalAlign") },
710     { MAP_CHAR_LEN("ControlBackground"), MAP_CHAR_LEN("BackgroundColor") },
711     { MAP_CHAR_LEN("ControlSymbolColor"), MAP_CHAR_LEN("SymbolColor") },
712     { MAP_CHAR_LEN("ControlBorder"), MAP_CHAR_LEN("Border") },
713     { MAP_CHAR_LEN("ControlBorderColor"), MAP_CHAR_LEN("BorderColor") },
714     { MAP_CHAR_LEN("ControlTextEmphasis"),  MAP_CHAR_LEN("FontEmphasisMark") },
715     { MAP_CHAR_LEN("ImageScaleMode"),  MAP_CHAR_LEN("ScaleMode") },
716     { MAP_CHAR_LEN("ControlWritingMode"), MAP_CHAR_LEN("WritingMode") },
717     { NULL,0, NULL, 0 }
718 };
719 
720 namespace
721 {
722     static bool lcl_convertPropertyName( const OUString& rApiName, OUString& rInternalName )
723     {
724         sal_uInt16 i = 0;
725         while( SvxShapeControlPropertyMapping[i].mpAPIName )
726         {
727             if( rApiName.reverseCompareToAsciiL( SvxShapeControlPropertyMapping[i].mpAPIName, SvxShapeControlPropertyMapping[i].mnAPINameLen ) == 0 )
728             {
729                 rInternalName = OUString( SvxShapeControlPropertyMapping[i].mpFormName, SvxShapeControlPropertyMapping[i].mnFormNameLen, RTL_TEXTENCODING_ASCII_US );
730             }
731             ++i;
732         }
733         return rInternalName.getLength() > 0;
734     }
735 
736     struct EnumConversionMap
737     {
738         sal_Int16   nAPIValue;
739         sal_Int16   nFormValue;
740     };
741 
742     EnumConversionMap aMapAdjustToAlign[] =
743     {
744         // note that order matters:
745         // lcl_convertTextAlignmentToParaAdjustment and lcl_convertParaAdjustmentToTextAlignment search this map from the _beginning_
746         // and use the first matching entry
747         {style::ParagraphAdjust_LEFT,           (sal_Int16)awt::TextAlign::LEFT},
748         {style::ParagraphAdjust_CENTER,         (sal_Int16)awt::TextAlign::CENTER},
749         {style::ParagraphAdjust_RIGHT,          (sal_Int16)awt::TextAlign::RIGHT},
750         {style::ParagraphAdjust_BLOCK,          (sal_Int16)awt::TextAlign::RIGHT},
751         {style::ParagraphAdjust_STRETCH,        (sal_Int16)awt::TextAlign::LEFT},
752         {-1,-1}
753     };
754 
755     static void lcl_mapFormToAPIValue( Any& _rValue, const EnumConversionMap* _pMap )
756     {
757         sal_Int16 nValue = sal_Int16();
758         OSL_VERIFY( _rValue >>= nValue );
759 
760         const EnumConversionMap* pEntry = _pMap;
761         while ( pEntry && ( pEntry->nFormValue != -1 ) )
762         {
763             if ( nValue == pEntry->nFormValue )
764             {
765                 _rValue <<= pEntry->nAPIValue;
766                 return;
767             }
768             ++pEntry;
769         }
770     }
771 
772     static void lcl_mapAPIToFormValue( Any& _rValue, const EnumConversionMap* _pMap )
773     {
774         sal_Int32 nValue = 0;
775         OSL_VERIFY( _rValue >>= nValue );
776 
777         const EnumConversionMap* pEntry = _pMap;
778         while ( pEntry && ( pEntry->nAPIValue != -1 ) )
779         {
780             if ( nValue == pEntry->nAPIValue )
781             {
782                 _rValue <<= pEntry->nFormValue;
783                 return;
784             }
785             ++pEntry;
786         }
787     }
788 
789     static void lcl_convertTextAlignmentToParaAdjustment( Any& rValue )
790     {
791         lcl_mapFormToAPIValue( rValue, aMapAdjustToAlign );
792     }
793 
794     static void lcl_convertParaAdjustmentToTextAlignment( Any& rValue )
795     {
796         lcl_mapAPIToFormValue( rValue, aMapAdjustToAlign );
797     }
798 
799     void convertVerticalAdjustToVerticalAlign( Any& _rValue ) SAL_THROW( ( lang::IllegalArgumentException ) )
800     {
801         if ( !_rValue.hasValue() )
802             return;
803 
804         drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
805         style::VerticalAlignment    eAlign  = style::VerticalAlignment_TOP;
806         if ( !( _rValue >>= eAdjust ) )
807             throw lang::IllegalArgumentException();
808         switch ( eAdjust )
809         {
810         case drawing::TextVerticalAdjust_TOP:    eAlign = style::VerticalAlignment_TOP; break;
811         case drawing::TextVerticalAdjust_BOTTOM: eAlign = style::VerticalAlignment_BOTTOM; break;
812         default:                                 eAlign = style::VerticalAlignment_MIDDLE; break;
813         }
814         _rValue <<= eAlign;
815     }
816 
817     void convertVerticalAlignToVerticalAdjust( Any& _rValue )
818     {
819         if ( !_rValue.hasValue() )
820             return;
821         style::VerticalAlignment    eAlign  = style::VerticalAlignment_TOP;
822         drawing::TextVerticalAdjust eAdjust = drawing::TextVerticalAdjust_TOP;
823         OSL_VERIFY( _rValue >>= eAlign );
824         switch ( eAlign )
825         {
826         case style::VerticalAlignment_TOP:    eAdjust = drawing::TextVerticalAdjust_TOP; break;
827         case style::VerticalAlignment_BOTTOM: eAdjust = drawing::TextVerticalAdjust_BOTTOM; break;
828         default:                              eAdjust = drawing::TextVerticalAdjust_CENTER; break;
829         }
830         _rValue <<= eAdjust;
831     }
832 }
833 
834 void SAL_CALL SvxShapeControl::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
835     throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException)
836 {
837     OUString aFormsName;
838     if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
839     {
840         uno::Reference< beans::XPropertySet > xControl( getControl(), uno::UNO_QUERY );
841         if( xControl.is() )
842         {
843             uno::Reference< beans::XPropertySetInfo > xInfo( xControl->getPropertySetInfo() );
844             if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
845             {
846                 uno::Any aConvertedValue( aValue );
847                 if ( aFormsName.equalsAscii( "FontSlant" ) )
848                 {
849                     awt::FontSlant nSlant;
850                     if( !(aValue >>= nSlant ) )
851                         throw lang::IllegalArgumentException();
852                     aConvertedValue <<= (sal_Int16)nSlant;
853                 }
854                 else if ( aFormsName.equalsAscii( "Align" ) )
855                 {
856                     lcl_convertParaAdjustmentToTextAlignment( aConvertedValue );
857                 }
858                 else if ( aFormsName.equalsAscii( "VerticalAlign" ) )
859                 {
860                     convertVerticalAdjustToVerticalAlign( aConvertedValue );
861                 }
862 
863                 xControl->setPropertyValue( aFormsName, aConvertedValue );
864             }
865         }
866     }
867     else
868     {
869         SvxShape::setPropertyValue( aPropertyName, aValue );
870     }
871 }
872 
873 uno::Any SAL_CALL SvxShapeControl::getPropertyValue( const OUString& aPropertyName )
874     throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
875 {
876     OUString aFormsName;
877     if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
878     {
879         uno::Reference< beans::XPropertySet > xControl( getControl(), uno::UNO_QUERY );
880 
881         uno::Any aValue;
882         if( xControl.is() )
883         {
884             uno::Reference< beans::XPropertySetInfo > xInfo( xControl->getPropertySetInfo() );
885             if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
886             {
887                 aValue = xControl->getPropertyValue( aFormsName );
888                 if ( aFormsName.equalsAscii( "FontSlant" ) )
889                 {
890                     awt::FontSlant eSlant = awt::FontSlant_NONE;
891                     sal_Int16 nSlant = sal_Int16();
892                     if ( aValue >>= nSlant )
893                     {
894                         eSlant = (awt::FontSlant)nSlant;
895                     }
896                     else
897                     {
898                         OSL_VERIFY( aValue >>= eSlant );
899                     }
900                     aValue <<= eSlant;
901                 }
902                 else if ( aFormsName.equalsAscii( "Align" ) )
903                 {
904                     lcl_convertTextAlignmentToParaAdjustment( aValue );
905                 }
906                 else if ( aFormsName.equalsAscii( "VerticalAlign" ) )
907                 {
908                     convertVerticalAlignToVerticalAdjust( aValue );
909                 }
910             }
911         }
912 
913         return aValue;
914     }
915     else
916     {
917         return SvxShape::getPropertyValue( aPropertyName );
918     }
919 
920 }
921 
922 // XPropertyState
923 beans::PropertyState SAL_CALL SvxShapeControl::getPropertyState( const ::rtl::OUString& PropertyName ) throw( beans::UnknownPropertyException, uno::RuntimeException )
924 {
925     OUString aFormsName;
926     if ( lcl_convertPropertyName( PropertyName, aFormsName ) )
927     {
928         uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
929         uno::Reference< beans::XPropertySet > xPropSet( getControl(), uno::UNO_QUERY );
930 
931         if( xControl.is() && xPropSet.is() )
932         {
933             uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
934             if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
935             {
936                 return xControl->getPropertyState( aFormsName );
937             }
938         }
939 
940         return beans::PropertyState_DEFAULT_VALUE;
941     }
942     else
943     {
944         return SvxShape::getPropertyState( PropertyName );
945     }
946 }
947 
948 void SAL_CALL SvxShapeControl::setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw( beans::UnknownPropertyException, uno::RuntimeException )
949 {
950     OUString aFormsName;
951     if ( lcl_convertPropertyName( PropertyName, aFormsName ) )
952     {
953         uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
954         uno::Reference< beans::XPropertySet > xPropSet( getControl(), uno::UNO_QUERY );
955 
956         if( xControl.is() && xPropSet.is() )
957         {
958             uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo() );
959             if( xInfo.is() && xInfo->hasPropertyByName( aFormsName ) )
960             {
961                 xControl->setPropertyToDefault( aFormsName );
962             }
963         }
964     }
965     else
966     {
967         SvxShape::setPropertyToDefault( PropertyName );
968     }
969 }
970 
971 uno::Any SAL_CALL SvxShapeControl::getPropertyDefault( const ::rtl::OUString& aPropertyName )
972     throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
973 {
974     OUString aFormsName;
975     if ( lcl_convertPropertyName( aPropertyName, aFormsName ) )
976     {
977         uno::Reference< beans::XPropertyState > xControl( getControl(), uno::UNO_QUERY );
978 
979         if( xControl.is() )
980         {
981             Any aDefault( xControl->getPropertyDefault( aFormsName ) );
982             if ( aFormsName.equalsAscii( "FontSlant" ) )
983             {
984                 sal_Int16 nSlant( 0 );
985                 aDefault >>= nSlant;
986                 aDefault <<= (awt::FontSlant)nSlant;
987             }
988             else if ( aFormsName.equalsAscii( "Align" ) )
989             {
990                 lcl_convertTextAlignmentToParaAdjustment( aDefault );
991             }
992             else if ( aFormsName.equalsAscii( "VerticalAlign" ) )
993             {
994                 convertVerticalAlignToVerticalAdjust( aDefault );
995             }
996             return aDefault;
997         }
998 
999         throw beans::UnknownPropertyException();
1000     }
1001     else
1002     {
1003         return SvxShape::getPropertyDefault( aPropertyName );
1004     }
1005 }
1006 
1007 
1008 /***********************************************************************
1009 * class SvxShapeDimensioning                                           *
1010 ***********************************************************************/
1011 
1012 //----------------------------------------------------------------------
1013 SvxShapeDimensioning::SvxShapeDimensioning( SdrObject* pObj ) throw()
1014 :   SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_DIMENSIONING), aSvxMapProvider.GetPropertySet(SVXMAP_DIMENSIONING, SdrObject::GetGlobalDrawObjectItemPool()) )
1015 {
1016 }
1017 
1018 //----------------------------------------------------------------------
1019 SvxShapeDimensioning::~SvxShapeDimensioning() throw()
1020 {
1021 }
1022 
1023 // ::com::sun::star::lang::XServiceInfo
1024 uno::Sequence< OUString > SAL_CALL SvxShapeDimensioning::getSupportedServiceNames() throw( uno::RuntimeException )
1025 {
1026     return SvxShapeText::getSupportedServiceNames();
1027 }
1028 
1029 /***********************************************************************
1030 *                                                                      *
1031 ***********************************************************************/
1032 
1033 //----------------------------------------------------------------------
1034 SvxShapeCircle::SvxShapeCircle( SdrObject* pObj ) throw()
1035 :   SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CIRCLE), aSvxMapProvider.GetPropertySet(SVXMAP_CIRCLE, SdrObject::GetGlobalDrawObjectItemPool()) )
1036 {
1037 }
1038 
1039 //----------------------------------------------------------------------
1040 SvxShapeCircle::~SvxShapeCircle() throw()
1041 {
1042 }
1043 
1044 // ::com::sun::star::lang::XServiceInfo
1045 // XServiceInfo
1046 uno::Sequence< OUString > SAL_CALL SvxShapeCircle::getSupportedServiceNames() throw( uno::RuntimeException )
1047 {
1048     return SvxShapeText::getSupportedServiceNames();
1049 }
1050 
1051 /***********************************************************************
1052 *                                                                      *
1053 ***********************************************************************/
1054 
1055 #include <svx/svdopath.hxx>
1056 
1057 //----------------------------------------------------------------------
1058 SvxShapePolyPolygon::SvxShapePolyPolygon( SdrObject* pObj , drawing::PolygonKind eNew )
1059  throw( com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException)
1060 : SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_POLYPOLYGON), aSvxMapProvider.GetPropertySet(SVXMAP_POLYPOLYGON, SdrObject::GetGlobalDrawObjectItemPool()) )
1061 , mePolygonKind( eNew )
1062 {
1063 }
1064 
1065 //----------------------------------------------------------------------
1066 SvxShapePolyPolygon::~SvxShapePolyPolygon() throw()
1067 {
1068 }
1069 
1070 basegfx::B2DPolyPolygon SAL_CALL ImplSvxPointSequenceSequenceToB2DPolyPolygon( const drawing::PointSequenceSequence* pOuterSequence) throw()
1071 {
1072     basegfx::B2DPolyPolygon aRetval;
1073 
1074     // Zeiger auf innere sequences holen
1075     const drawing::PointSequence* pInnerSequence = pOuterSequence->getConstArray();
1076     const drawing::PointSequence* pInnerSeqEnd   = pInnerSequence + pOuterSequence->getLength();
1077 
1078     for(;pInnerSequence != pInnerSeqEnd; ++pInnerSequence)
1079     {
1080         // Neues Polygon vorbereiten
1081         basegfx::B2DPolygon aNewPolygon;
1082 
1083         // Zeiger auf Arrays holen
1084         const awt::Point* pArray    = pInnerSequence->getConstArray();
1085         const awt::Point* pArrayEnd = pArray + pInnerSequence->getLength();
1086 
1087         for(;pArray != pArrayEnd;++pArray)
1088         {
1089             aNewPolygon.append(basegfx::B2DPoint(pArray->X, pArray->Y));
1090         }
1091 
1092         // check for closed state flag
1093         basegfx::tools::checkClosed(aNewPolygon);
1094 
1095         // Neues Teilpolygon einfuegen
1096         aRetval.append(aNewPolygon);
1097     }
1098 
1099     return aRetval;
1100 }
1101 
1102 //----------------------------------------------------------------------
1103 
1104 bool SvxShapePolyPolygon::setPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1105 {
1106     switch( pProperty->nWID )
1107     {
1108     case OWN_ATTR_VALUE_POLYPOLYGON:
1109     {
1110         if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PointSequenceSequence*)0) ) )
1111         {
1112             basegfx::B2DPolyPolygon aNewPolyPolygon(ImplSvxPointSequenceSequenceToB2DPolyPolygon( (drawing::PointSequenceSequence*)rValue.getValue()));
1113             SetPolygon(aNewPolyPolygon);
1114             return true;
1115         }
1116         break;
1117     }
1118     case OWN_ATTR_BASE_GEOMETRY:
1119     {
1120         if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PointSequenceSequence*)0)))
1121         {
1122             if( mpObj.is() )
1123             {
1124                 basegfx::B2DPolyPolygon aNewPolyPolygon;
1125                 basegfx::B2DHomMatrix aNewHomogenMatrix;
1126 
1127                 mpObj->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
1128                 aNewPolyPolygon = ImplSvxPointSequenceSequenceToB2DPolyPolygon((drawing::PointSequenceSequence*)rValue.getValue());
1129                 mpObj->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
1130             }
1131             return true;
1132         }
1133         break;
1134     }
1135     case OWN_ATTR_VALUE_POLYGON:
1136     {
1137         if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PointSequenceSequence*)0) ))
1138         {
1139             drawing::PointSequence* pSequence = (drawing::PointSequence*)rValue.getValue();
1140 
1141             // Neues Polygon vorbereiten
1142             basegfx::B2DPolygon aNewPolygon;
1143 
1144             // Zeiger auf Arrays holen
1145             // Zeiger auf Arrays holen
1146             const awt::Point* pArray    = pSequence->getConstArray();
1147             const awt::Point* pArrayEnd = pArray + pSequence->getLength();
1148 
1149             for(;pArray != pArrayEnd;++pArray)
1150             {
1151                 aNewPolygon.append(basegfx::B2DPoint(pArray->X, pArray->Y));
1152             }
1153 
1154             // check for closed state flag
1155             basegfx::tools::checkClosed(aNewPolygon);
1156 
1157             // Polygon setzen
1158             SetPolygon(basegfx::B2DPolyPolygon(aNewPolygon));
1159             return true;
1160         }
1161         break;
1162     }
1163     default:
1164         return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
1165     }
1166 
1167     throw lang::IllegalArgumentException();
1168 }
1169 
1170 void SAL_CALL B2DPolyPolygonToSvxPointSequenceSequence( const basegfx::B2DPolyPolygon& rPolyPoly, drawing::PointSequenceSequence& rRetval )
1171 {
1172     if( (sal_uInt32)rRetval.getLength() != rPolyPoly.count() )
1173         rRetval.realloc( rPolyPoly.count() );
1174 
1175     // Zeiger auf aeussere Arrays holen
1176     drawing::PointSequence* pOuterSequence = rRetval.getArray();
1177 
1178     for(sal_uInt32 a(0L); a < rPolyPoly.count(); a++)
1179     {
1180         // Einzelpolygon holen
1181         const basegfx::B2DPolygon aPoly(rPolyPoly.getB2DPolygon(a));
1182 
1183         // #i75974# take closed stae into account, the API polygon still uses the old closed definition
1184         // with last/first point are identical (cannot hold information about open polygons with identical
1185         // first and last point, though)
1186         const sal_uInt32 nPointCount(aPoly.count());
1187         const bool bIsClosed(aPoly.isClosed());
1188 
1189         // Platz in Arrays schaffen
1190         pOuterSequence->realloc(bIsClosed ? nPointCount + 1 : nPointCount);
1191 
1192         // Pointer auf arrays holen
1193         awt::Point* pInnerSequence = pOuterSequence->getArray();
1194 
1195         for(sal_uInt32 b(0L); b < nPointCount; b++)
1196         {
1197             const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(b));
1198             *pInnerSequence = awt::Point( basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()) );
1199             pInnerSequence++;
1200         }
1201 
1202         // #i75974# copy first point
1203         if(bIsClosed)
1204         {
1205             *pInnerSequence = *pOuterSequence->getArray();
1206         }
1207 
1208         pOuterSequence++;
1209     }
1210 }
1211 
1212 //----------------------------------------------------------------------
1213 
1214 bool SvxShapePolyPolygon::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1215 {
1216     switch( pProperty->nWID )
1217     {
1218     case OWN_ATTR_VALUE_POLYPOLYGON:
1219     {
1220         // PolyPolygon in eine struct PolyPolygon packen
1221         const basegfx::B2DPolyPolygon& rPolyPoly = GetPolygon();
1222         drawing::PointSequenceSequence aRetval( rPolyPoly.count() );
1223 
1224         B2DPolyPolygonToSvxPointSequenceSequence( rPolyPoly, aRetval );
1225 
1226         rValue <<= aRetval;
1227         break;
1228     }
1229     case OWN_ATTR_BASE_GEOMETRY:
1230     {
1231         // pack a PolyPolygon in struct PolyPolygon
1232         basegfx::B2DPolyPolygon aNewPolyPolygon;
1233         basegfx::B2DHomMatrix aNewHomogenMatrix;
1234 
1235         if(mpObj.is())
1236             mpObj->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
1237 
1238         drawing::PointSequenceSequence aRetval(aNewPolyPolygon.count());
1239         B2DPolyPolygonToSvxPointSequenceSequence(aNewPolyPolygon, aRetval);
1240         rValue <<= aRetval;
1241         break;
1242     }
1243     case OWN_ATTR_VALUE_POLYGON:
1244     {
1245         // PolyPolygon in eine struct PolyPolygon packen
1246         const basegfx::B2DPolyPolygon& rPolyPoly = GetPolygon();
1247 
1248         sal_Int32 nCount = 0;
1249         if( rPolyPoly.count() > 0 )
1250             nCount = rPolyPoly.getB2DPolygon(0L).count();
1251 
1252         drawing::PointSequence aRetval( nCount );
1253 
1254         if( nCount > 0 )
1255         {
1256             // Einzelpolygon holen
1257             const basegfx::B2DPolygon aPoly(rPolyPoly.getB2DPolygon(0L));
1258 
1259             // Pointer auf arrays holen
1260             awt::Point* pSequence = aRetval.getArray();
1261 
1262             for(sal_Int32 b=0;b<nCount;b++)
1263             {
1264                 const basegfx::B2DPoint aPoint(aPoly.getB2DPoint(b));
1265                 *pSequence++ = awt::Point( basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY()) );
1266             }
1267         }
1268 
1269         rValue <<= aRetval;
1270         break;
1271     }
1272     case OWN_ATTR_VALUE_POLYGONKIND:
1273     {
1274         rValue <<= GetPolygonKind();
1275         break;
1276     }
1277     default:
1278         return SvxShapeText::getPropertyValueImpl( rName, pProperty, rValue );
1279     }
1280 
1281     return true;
1282 }
1283 
1284 //----------------------------------------------------------------------
1285 drawing::PolygonKind SvxShapePolyPolygon::GetPolygonKind() const throw()
1286 {
1287     return mePolygonKind;
1288 }
1289 
1290 //----------------------------------------------------------------------
1291 void SvxShapePolyPolygon::SetPolygon(const basegfx::B2DPolyPolygon& rNew) throw()
1292 {
1293     OGuard aGuard( Application::GetSolarMutex() );
1294 
1295     if(mpObj.is())
1296         ((SdrPathObj*)mpObj.get())->SetPathPoly(rNew);
1297 }
1298 
1299 //----------------------------------------------------------------------
1300 basegfx::B2DPolyPolygon SvxShapePolyPolygon::GetPolygon() const throw()
1301 {
1302     OGuard aGuard( Application::GetSolarMutex() );
1303 
1304     if(mpObj.is())
1305     {
1306         return ((SdrPathObj*)mpObj.get())->GetPathPoly();
1307     }
1308     else
1309     {
1310         return basegfx::B2DPolyPolygon();
1311     }
1312 }
1313 
1314 // ::com::sun::star::lang::XServiceInfo
1315 uno::Sequence< OUString > SAL_CALL SvxShapePolyPolygon::getSupportedServiceNames() throw( uno::RuntimeException )
1316 {
1317     return SvxShapeText::getSupportedServiceNames();
1318 }
1319 
1320 /***********************************************************************
1321 * class SvxShapePolyPolygonBezier                                      *
1322 ***********************************************************************/
1323 #include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
1324 #include <com/sun/star/drawing/FlagSequence.hpp>
1325 //----------------------------------------------------------------------
1326 SvxShapePolyPolygonBezier::SvxShapePolyPolygonBezier( SdrObject* pObj , drawing::PolygonKind eNew ) throw()
1327 :   SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_POLYPOLYGONBEZIER), aSvxMapProvider.GetPropertySet(SVXMAP_POLYPOLYGONBEZIER, SdrObject::GetGlobalDrawObjectItemPool()) )
1328 ,   mePolygonKind( eNew )
1329 {
1330 }
1331 
1332 //----------------------------------------------------------------------
1333 SvxShapePolyPolygonBezier::~SvxShapePolyPolygonBezier() throw()
1334 {
1335 }
1336 
1337 basegfx::B2DPolyPolygon SvxConvertPolyPolygonBezierToB2DPolyPolygon(const drawing::PolyPolygonBezierCoords* pSourcePolyPolygon)
1338     throw( IllegalArgumentException )
1339 {
1340     const sal_Int32 nOuterSequenceCount(pSourcePolyPolygon->Coordinates.getLength());
1341     basegfx::B2DPolyPolygon aNewPolyPolygon;
1342 
1343     if(pSourcePolyPolygon->Flags.getLength() != nOuterSequenceCount)
1344     {
1345         throw IllegalArgumentException();
1346     }
1347 
1348     // get pointers to inner sequence
1349     const drawing::PointSequence* pInnerSequence = pSourcePolyPolygon->Coordinates.getConstArray();
1350     const drawing::FlagSequence* pInnerSequenceFlags = pSourcePolyPolygon->Flags.getConstArray();
1351 
1352     for(sal_Int32 a(0); a < nOuterSequenceCount; a++)
1353     {
1354         const sal_Int32 nInnerSequenceCount(pInnerSequence->getLength());
1355 
1356         if(pInnerSequenceFlags->getLength() != nInnerSequenceCount)
1357         {
1358             throw IllegalArgumentException();
1359         }
1360 
1361         // prepare new polygon
1362         basegfx::B2DPolygon aNewPolygon;
1363         const awt::Point* pArray = pInnerSequence->getConstArray();
1364         const drawing::PolygonFlags* pArrayFlags = pInnerSequenceFlags->getConstArray();
1365 
1366         // get first point and flag
1367         basegfx::B2DPoint aNewCoordinatePair(pArray->X, pArray->Y); pArray++;
1368         XPolyFlags ePolyFlag((XPolyFlags)((sal_uInt16)*pArrayFlags)); pArrayFlags++;
1369         basegfx::B2DPoint aControlA;
1370         basegfx::B2DPoint aControlB;
1371 
1372         // first point is not allowed to be a control point
1373         if(XPOLY_CONTROL == ePolyFlag)
1374         {
1375             throw IllegalArgumentException();
1376         }
1377 
1378         // add first point as start point
1379         aNewPolygon.append(aNewCoordinatePair);
1380 
1381         for(sal_Int32 b(1); b < nInnerSequenceCount;)
1382         {
1383             // prepare loop
1384             bool bControlA(false);
1385             bool bControlB(false);
1386 
1387             // get next point and flag
1388             aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
1389             ePolyFlag = XPolyFlags((XPolyFlags)((sal_uInt16)*pArrayFlags));
1390             pArray++; pArrayFlags++; b++;
1391 
1392             if(b < nInnerSequenceCount && XPOLY_CONTROL == ePolyFlag)
1393             {
1394                 aControlA = aNewCoordinatePair;
1395                 bControlA = true;
1396 
1397                 // get next point and flag
1398                 aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
1399                 ePolyFlag = XPolyFlags((XPolyFlags)((sal_uInt16)*pArrayFlags));
1400                 pArray++; pArrayFlags++; b++;
1401             }
1402 
1403             if(b < nInnerSequenceCount && XPOLY_CONTROL == ePolyFlag)
1404             {
1405                 aControlB = aNewCoordinatePair;
1406                 bControlB = true;
1407 
1408                 // get next point and flag
1409                 aNewCoordinatePair = basegfx::B2DPoint(pArray->X, pArray->Y);
1410                 ePolyFlag = XPolyFlags((XPolyFlags)((sal_uInt16)*pArrayFlags));
1411                 pArray++; pArrayFlags++; b++;
1412             }
1413 
1414             // two or no control points are consumed, another one would be an error.
1415             // It's also an error if only one control point was read
1416             if(XPOLY_CONTROL == ePolyFlag || bControlA != bControlB)
1417             {
1418                 throw IllegalArgumentException();
1419             }
1420 
1421             // the previous writes used the B2DPolyPoygon -> PolyPolygon converter
1422             // which did not create minimal PolyPolygons, but created all control points
1423             // as null vectors (identical points). Because of the former P(CA)(CB)-norm of
1424             // B2DPolygon and it's unused sign of being the zero-vector and CA and CB being
1425             // relative to P, an empty edge was exported as P == CA == CB. Luckily, the new
1426             // export format can be read without errors by the old OOo-versions, so we need only
1427             // to correct here at read and do not need to export a wrong but compatible version
1428             // for the future.
1429             if(bControlA
1430                 && aControlA.equal(aControlB)
1431                 && aControlA.equal(aNewPolygon.getB2DPoint(aNewPolygon.count() - 1)))
1432             {
1433                 bControlA = bControlB = false;
1434             }
1435 
1436             if(bControlA)
1437             {
1438                 // add bezier edge
1439                 aNewPolygon.appendBezierSegment(aControlA, aControlB, aNewCoordinatePair);
1440             }
1441             else
1442             {
1443                 // add edge
1444                 aNewPolygon.append(aNewCoordinatePair);
1445             }
1446         }
1447 
1448         // next sequence
1449         pInnerSequence++;
1450         pInnerSequenceFlags++;
1451 
1452         // #i72807# API import uses old line start/end-equal definition for closed,
1453         // so we need to correct this to closed state here
1454         basegfx::tools::checkClosed(aNewPolygon);
1455 
1456         // add new subpolygon
1457         aNewPolyPolygon.append(aNewPolygon);
1458     }
1459 
1460     return aNewPolyPolygon;
1461 }
1462 
1463 //----------------------------------------------------------------------
1464 
1465 bool SvxShapePolyPolygonBezier::setPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1466 {
1467     switch( pProperty->nWID )
1468     {
1469     case OWN_ATTR_VALUE_POLYPOLYGONBEZIER:
1470     {
1471         if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PolyPolygonBezierCoords*)0) ) )
1472         {
1473             basegfx::B2DPolyPolygon aNewPolyPolygon(SvxConvertPolyPolygonBezierToB2DPolyPolygon( (drawing::PolyPolygonBezierCoords*)rValue.getValue()));
1474             SetPolygon(aNewPolyPolygon);
1475             return true;
1476         }
1477         break;
1478     }
1479     case OWN_ATTR_BASE_GEOMETRY:
1480     {
1481         if( rValue.getValue() && (rValue.getValueType() == ::getCppuType(( const drawing::PolyPolygonBezierCoords*)0)) )
1482         {
1483             if( mpObj.is() )
1484             {
1485                 basegfx::B2DPolyPolygon aNewPolyPolygon;
1486                 basegfx::B2DHomMatrix aNewHomogenMatrix;
1487 
1488                 mpObj->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
1489                 aNewPolyPolygon = SvxConvertPolyPolygonBezierToB2DPolyPolygon((drawing::PolyPolygonBezierCoords*)rValue.getValue());
1490                 mpObj->TRSetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
1491             }
1492             return true;
1493         }
1494         break;
1495     }
1496     default:
1497         return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
1498     }
1499 
1500     throw IllegalArgumentException();
1501 }
1502 
1503 void SvxConvertB2DPolyPolygonToPolyPolygonBezier( const basegfx::B2DPolyPolygon& rPolyPoly, drawing::PolyPolygonBezierCoords& rRetval )
1504 {
1505     // use PolyPolygon converter as base. Since PolyPolygonBezierCoords uses
1506     // integer coordinates, this is no precision loss at all.
1507     const PolyPolygon aPolyPoly(rPolyPoly);
1508 
1509     // Polygone innerhalb vrobereiten
1510     rRetval.Coordinates.realloc((sal_Int32)aPolyPoly.Count());
1511     rRetval.Flags.realloc((sal_Int32)aPolyPoly.Count());
1512 
1513     // Zeiger auf aeussere Arrays holen
1514     drawing::PointSequence* pOuterSequence = rRetval.Coordinates.getArray();
1515     drawing::FlagSequence*  pOuterFlags = rRetval.Flags.getArray();
1516 
1517     for(sal_uInt16 a=0;a<aPolyPoly.Count();a++)
1518     {
1519         // Einzelpolygon holen
1520         const Polygon& rPoly = aPolyPoly[a];
1521 
1522         // Platz in Arrays schaffen
1523         pOuterSequence->realloc((sal_Int32)rPoly.GetSize());
1524         pOuterFlags->realloc((sal_Int32)rPoly.GetSize());
1525 
1526         // Pointer auf arrays holen
1527         awt::Point* pInnerSequence = pOuterSequence->getArray();
1528         drawing::PolygonFlags* pInnerFlags = pOuterFlags->getArray();
1529 
1530         for(sal_uInt16 b=0;b<rPoly.GetSize();b++)
1531         {
1532             *pInnerSequence++ = awt::Point( rPoly[b].X(), rPoly[b].Y() );
1533             *pInnerFlags++ = (drawing::PolygonFlags)((sal_uInt16)rPoly.GetFlags(b));
1534         }
1535 
1536         pOuterSequence++;
1537         pOuterFlags++;
1538     }
1539 }
1540 
1541 //----------------------------------------------------------------------
1542 
1543 bool SvxShapePolyPolygonBezier::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1544 {
1545     switch( pProperty->nWID )
1546     {
1547     case OWN_ATTR_VALUE_POLYPOLYGONBEZIER:
1548     {
1549         // PolyPolygon in eine struct PolyPolygon packen
1550         const basegfx::B2DPolyPolygon& rPolyPoly = GetPolygon();
1551         drawing::PolyPolygonBezierCoords aRetval;
1552         SvxConvertB2DPolyPolygonToPolyPolygonBezier(rPolyPoly, aRetval );
1553 
1554         rValue <<= aRetval;
1555         break;
1556     }
1557     case OWN_ATTR_BASE_GEOMETRY:
1558     {
1559         // PolyPolygon in eine struct PolyPolygon packen
1560         basegfx::B2DPolyPolygon aNewPolyPolygon;
1561         basegfx::B2DHomMatrix aNewHomogenMatrix;
1562         mpObj.get()->TRGetBaseGeometry(aNewHomogenMatrix, aNewPolyPolygon);
1563         drawing::PolyPolygonBezierCoords aRetval;
1564         SvxConvertB2DPolyPolygonToPolyPolygonBezier(aNewPolyPolygon, aRetval);
1565 
1566         rValue <<= aRetval;
1567         break;
1568     }
1569     case OWN_ATTR_VALUE_POLYGONKIND:
1570     {
1571         rValue <<= mePolygonKind;
1572         break;
1573     }
1574     default:
1575         return SvxShapeText::getPropertyValueImpl( rName, pProperty, rValue );
1576     }
1577     return true;
1578 }
1579 
1580 //----------------------------------------------------------------------
1581 drawing::PolygonKind SvxShapePolyPolygonBezier::GetPolygonKind() const throw()
1582 {
1583     return mePolygonKind;
1584 }
1585 
1586 //----------------------------------------------------------------------
1587 void SvxShapePolyPolygonBezier::SetPolygon(const basegfx::B2DPolyPolygon& rNew) throw()
1588 {
1589     OGuard aGuard( Application::GetSolarMutex() );
1590 
1591     if(mpObj.is())
1592         static_cast<SdrPathObj*>(mpObj.get())->SetPathPoly(rNew);
1593 }
1594 
1595 //----------------------------------------------------------------------
1596 basegfx::B2DPolyPolygon SvxShapePolyPolygonBezier::GetPolygon() const throw()
1597 {
1598     OGuard aGuard( Application::GetSolarMutex() );
1599 
1600     if(mpObj.is())
1601     {
1602         return static_cast<SdrPathObj*>(mpObj.get())->GetPathPoly();
1603     }
1604     else
1605     {
1606         return basegfx::B2DPolyPolygon();
1607     }
1608 }
1609 
1610 
1611 // ::com::sun::star::lang::XServiceInfo
1612 uno::Sequence< OUString > SAL_CALL SvxShapePolyPolygonBezier::getSupportedServiceNames() throw( uno::RuntimeException )
1613 {
1614     return SvxShapeText::getSupportedServiceNames();
1615 }
1616 
1617 /***********************************************************************
1618 * class SvxGraphicObject                                               *
1619 ***********************************************************************/
1620 #include <com/sun/star/awt/XBitmap.hpp>
1621 #include <vcl/cvtgrf.hxx>
1622 #include <svx/svdograf.hxx>
1623 #ifndef SVX_LIGHT
1624 #ifndef _SFXDOCFILE_HXX
1625 #include <sfx2/docfile.hxx>
1626 #endif
1627 #include <sfx2/app.hxx>
1628 #include <sfx2/fcontnr.hxx>
1629 #endif
1630 
1631 #include "toolkit/unohlp.hxx"
1632 
1633 //----------------------------------------------------------------------
1634 SvxGraphicObject::SvxGraphicObject( SdrObject* pObj ) throw()
1635 :   SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_GRAPHICOBJECT), aSvxMapProvider.GetPropertySet(SVXMAP_GRAPHICOBJECT, SdrObject::GetGlobalDrawObjectItemPool()) )
1636 {
1637 }
1638 
1639 //----------------------------------------------------------------------
1640 SvxGraphicObject::~SvxGraphicObject() throw()
1641 {
1642 }
1643 
1644 //----------------------------------------------------------------------
1645 
1646 bool SvxGraphicObject::setPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, const ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1647 {
1648     bool bOk = false;
1649     switch( pProperty->nWID )
1650     {
1651     case OWN_ATTR_VALUE_FILLBITMAP:
1652     {
1653         if( rValue.getValue() )
1654         {
1655             if( rValue.getValueType() == ::getCppuType(( const uno::Sequence< sal_Int8 >*)0) )
1656             {
1657                 uno::Sequence<sal_Int8>* pSeq( (uno::Sequence<sal_Int8>*)rValue.getValue() );
1658                 SvMemoryStream  aMemStm;
1659                 Graphic         aGraphic;
1660 
1661                 aMemStm.SetBuffer( (char*)pSeq->getConstArray(), pSeq->getLength(), sal_False, pSeq->getLength() );
1662 
1663                 if( GraphicConverter::Import( aMemStm, aGraphic ) == ERRCODE_NONE )
1664                 {
1665                     static_cast<SdrGrafObj*>(mpObj.get())->SetGraphic(aGraphic);
1666                     bOk = true;
1667                 }
1668             }
1669         }
1670         else if( (rValue.getValueType() == awt::XBitmap::static_type()) || (rValue.getValueType() == graphic::XGraphic::static_type()))
1671         {
1672             Reference< graphic::XGraphic> xGraphic( rValue, UNO_QUERY );
1673             if( xGraphic.is() )
1674             {
1675                 ((SdrGrafObj*)mpObj.get())->SetGraphic(Graphic(xGraphic));
1676                 bOk = true;
1677             }
1678             else
1679             {
1680                 // Bitmap in das Objekt packen
1681                 Reference< awt::XBitmap > xBmp( rValue, UNO_QUERY );
1682                 if( xBmp.is() )
1683                 {
1684                     // Bitmap einsetzen
1685                     Graphic aGraphic(VCLUnoHelper::GetBitmap( xBmp ));
1686                     ((SdrGrafObj*)mpObj.get())->SetGraphic(aGraphic);
1687                     bOk = true;
1688                 }
1689             }
1690         }
1691         break;
1692     }
1693     case OWN_ATTR_GRAFURL:
1694     {
1695         OUString aURL;
1696         if( rValue >>= aURL )
1697         {
1698             if( aURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 )
1699             {
1700                 // graphic manager url
1701                 aURL = aURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 );
1702                 String aTmpStr(aURL);
1703                 ByteString aUniqueID( aTmpStr, RTL_TEXTENCODING_UTF8 );
1704                 GraphicObject aGrafObj( aUniqueID );
1705 
1706                 // #101808# since loading a graphic can cause a reschedule of the office
1707                 //          it is possible that our shape is removed while where in this
1708                 //          method.
1709                 if( mpObj.is() )
1710                 {
1711                     static_cast<SdrGrafObj*>(mpObj.get())->ReleaseGraphicLink();
1712                     static_cast<SdrGrafObj*>(mpObj.get())->SetGraphicObject( aGrafObj );
1713                 }
1714             }
1715             else if( aURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPKGPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPKGPREFIX ) ) != 0 )
1716             {
1717                 // normal link
1718                 String              aFilterName;
1719                 const SfxFilter*    pSfxFilter = NULL;
1720                 SfxMedium           aSfxMedium( aURL, STREAM_READ | STREAM_SHARE_DENYNONE, sal_False );
1721 
1722                 SFX_APP()->GetFilterMatcher().GuessFilter( aSfxMedium, &pSfxFilter, SFX_FILTER_IMPORT, SFX_FILTER_NOTINSTALLED | SFX_FILTER_EXECUTABLE );
1723 
1724                 if( !pSfxFilter )
1725                 {
1726                     INetURLObject aURLObj( aURL );
1727 
1728                     if( aURLObj.GetProtocol() == INET_PROT_NOT_VALID )
1729                     {
1730                         String aValidURL;
1731 
1732                         if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aURL, aValidURL ) )
1733                             aURLObj = INetURLObject( aValidURL );
1734                     }
1735 
1736                     if( aURLObj.GetProtocol() != INET_PROT_NOT_VALID )
1737                     {
1738                         GraphicFilter* pGrfFilter = GraphicFilter::GetGraphicFilter();
1739                         aFilterName = pGrfFilter->GetImportFormatName( pGrfFilter->GetImportFormatNumberForShortName( aURLObj.getExtension() ) );
1740                     }
1741                 }
1742                 else
1743                     aFilterName = pSfxFilter->GetFilterName();
1744 
1745                 // #101808# since loading a graphic can cause a reschedule of the office
1746                 //          it is possible that our shape is removed while where in this
1747                 //          method.
1748                 if( mpObj.is() )
1749                     static_cast<SdrGrafObj*>(mpObj.get())->SetGraphicLink( aURL, aFilterName );
1750 
1751             }
1752             bOk = true;
1753         }
1754         break;
1755     }
1756 
1757     case OWN_ATTR_GRAFSTREAMURL:
1758     {
1759         OUString aStreamURL;
1760 
1761         if( rValue >>= aStreamURL )
1762         {
1763             if( aStreamURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPKGPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPKGPREFIX ) ) != 0 )
1764                 aStreamURL = OUString();
1765 
1766             if( mpObj.is() )
1767             {
1768                 static_cast<SdrGrafObj*>(mpObj.get())->SetGrafStreamURL( aStreamURL );
1769                 static_cast<SdrGrafObj*>(mpObj.get())->ForceSwapOut();
1770             }
1771             bOk = true;
1772         }
1773         break;
1774     }
1775 
1776     case OWN_ATTR_VALUE_GRAPHIC:
1777     {
1778         Reference< graphic::XGraphic > xGraphic( rValue, uno::UNO_QUERY );
1779         if( xGraphic.is() )
1780         {
1781             static_cast< SdrGrafObj*>( mpObj.get() )->SetGraphic( xGraphic );
1782             bOk = true;
1783         }
1784         break;
1785     }
1786     default:
1787         return SvxShapeText::setPropertyValueImpl( rName, pProperty, rValue );
1788     }
1789 
1790     if( !bOk )
1791         throw lang::IllegalArgumentException();
1792 
1793     if( mpModel )
1794         mpModel->SetChanged();
1795 
1796     return true;
1797 }
1798 
1799 //----------------------------------------------------------------------
1800 
1801 bool SvxGraphicObject::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
1802 {
1803     switch( pProperty->nWID )
1804     {
1805     case OWN_ATTR_VALUE_FILLBITMAP:
1806     {
1807         sal_Bool bSwapped = static_cast< SdrGrafObj* >( mpObj.get() )->IsSwappedOut();
1808         const Graphic& rGraphic = static_cast< SdrGrafObj*>( mpObj.get() )->GetGraphic();
1809 
1810         if(rGraphic.GetType() != GRAPHIC_GDIMETAFILE)
1811         {
1812             // Objekt in eine Bitmap packen
1813             Reference< ::com::sun::star::awt::XBitmap >  xBitmap( VCLUnoHelper::CreateBitmap(static_cast< SdrGrafObj*>( mpObj.get() )->GetGraphic().GetBitmapEx()) );
1814             rValue <<= xBitmap;
1815         }
1816         else
1817         {
1818             SvMemoryStream aDestStrm( 65535, 65535 );
1819 
1820             ConvertGDIMetaFileToWMF( rGraphic.GetGDIMetaFile(), aDestStrm, NULL, sal_False );
1821             const uno::Sequence<sal_Int8> aSeq(
1822                 static_cast< const sal_Int8* >(aDestStrm.GetData()),
1823                 aDestStrm.GetEndOfData());
1824             rValue <<= aSeq;
1825         }
1826         if ( bSwapped )
1827             static_cast< SdrGrafObj* >( mpObj.get() )->ForceSwapOut();
1828         break;
1829     }
1830 
1831     case OWN_ATTR_GRAFURL:
1832     {
1833         if( static_cast< SdrGrafObj*>( mpObj.get() )->IsLinkedGraphic() )
1834         {
1835             rValue <<= OUString( static_cast< SdrGrafObj*>( mpObj.get() )->GetFileName() );
1836         }
1837         else
1838         {
1839             sal_Bool bSwapped = static_cast< SdrGrafObj* >( mpObj.get() )->IsSwappedOut();
1840             const GraphicObject& rGrafObj = static_cast< SdrGrafObj*>( mpObj.get() )->GetGraphicObject(true);
1841             OUString aURL( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
1842             aURL += OUString::createFromAscii( rGrafObj.GetUniqueID().GetBuffer() );
1843             rValue <<= aURL;
1844             if ( bSwapped )
1845                 static_cast< SdrGrafObj* >( mpObj.get() )->ForceSwapOut();
1846         }
1847         break;
1848     }
1849 
1850     case OWN_ATTR_GRAFSTREAMURL:
1851     {
1852         const OUString  aStreamURL( ( (SdrGrafObj*) mpObj.get() )->GetGrafStreamURL() );
1853         if( aStreamURL.getLength() )
1854             rValue <<= aStreamURL;
1855         break;
1856     }
1857 
1858     case OWN_ATTR_VALUE_GRAPHIC:
1859     {
1860         sal_Bool bSwapped = static_cast< SdrGrafObj* >( mpObj.get() )->IsSwappedOut();
1861         Reference< graphic::XGraphic > xGraphic( static_cast< SdrGrafObj* >( mpObj.get() )->GetGraphic().GetXGraphic() );
1862         rValue <<= xGraphic;
1863         if ( bSwapped )
1864             static_cast< SdrGrafObj* >( mpObj.get() )->ForceSwapOut();
1865         break;
1866     }
1867 
1868     case OWN_ATTR_GRAPHIC_STREAM:
1869     {
1870         rValue <<= static_cast< SdrGrafObj* >( mpObj.get() )->getInputStream();
1871         break;
1872     }
1873     default:
1874         return SvxShapeText::getPropertyValueImpl(rName, pProperty,rValue);
1875     }
1876 
1877     return true;
1878 }
1879 
1880 ///////////////////////////////////////////////////////////////////////
1881 
1882 SvxShapeCaption::SvxShapeCaption( SdrObject* pObj ) throw()
1883 : SvxShapeText( pObj, aSvxMapProvider.GetMap(SVXMAP_CAPTION), aSvxMapProvider.GetPropertySet(SVXMAP_CAPTION, SdrObject::GetGlobalDrawObjectItemPool()) )
1884 {
1885 }
1886 
1887 SvxShapeCaption::~SvxShapeCaption() throw()
1888 {
1889 }
1890 
1891 /***********************************************************************
1892 * class SvxCustomShape                                                   *
1893 ***********************************************************************/
1894 
1895 SvxCustomShape::SvxCustomShape( SdrObject* pObj )  throw() :
1896     SvxShapeText( pObj, aSvxMapProvider.GetMap( SVXMAP_CUSTOMSHAPE ), aSvxMapProvider.GetPropertySet(SVXMAP_CUSTOMSHAPE, SdrObject::GetGlobalDrawObjectItemPool()) )
1897 {
1898 }
1899 
1900 //----------------------------------------------------------------------
1901 SvxCustomShape::~SvxCustomShape() throw()
1902 {
1903 }
1904 
1905 //----------------------------------------------------------------------
1906 
1907 void SvxCustomShape::Create( SdrObject* pNewObj, SvxDrawPage* pNewPage )
1908 {
1909     SvxShapeText::Create( pNewObj, pNewPage );
1910 }
1911 
1912 //----------------------------------------------------------------------
1913 
1914 uno::Any SAL_CALL SvxCustomShape::queryInterface( const uno::Type & rType )
1915     throw(uno::RuntimeException)
1916 {
1917     return SvxShapeText::queryInterface( rType );
1918 }
1919 
1920 uno::Any SAL_CALL SvxCustomShape::queryAggregation( const uno::Type & rType )
1921     throw(uno::RuntimeException)
1922 {
1923     ::com::sun::star::uno::Any aReturn = SvxShapeText::queryAggregation( rType );
1924     if ( !aReturn.hasValue() )
1925         aReturn = ::cppu::queryInterface(rType, static_cast<drawing::XEnhancedCustomShapeDefaulter*>(this) );
1926     return aReturn;
1927 }
1928 
1929 void SAL_CALL SvxCustomShape::acquire() throw ( )
1930 {
1931     SvxShapeText::acquire();
1932 }
1933 
1934 void SAL_CALL SvxCustomShape::release() throw ( )
1935 {
1936     SvxShapeText::release();
1937 }
1938 
1939 //----------------------------------------------------------------------
1940 
1941 uno::Sequence< uno::Type > SAL_CALL SvxCustomShape::getTypes()
1942     throw (uno::RuntimeException)
1943 {
1944     return SvxShapeText::getTypes();
1945 }
1946 
1947 uno::Sequence< sal_Int8 > SAL_CALL SvxCustomShape::getImplementationId()
1948     throw (uno::RuntimeException)
1949 {
1950     static uno::Sequence< sal_Int8 > aId;
1951     if( aId.getLength() == 0 )
1952     {
1953         aId.realloc( 16 );
1954         rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
1955     }
1956     return aId;
1957 }
1958 
1959 // ::com::sun::star::drawing::XShape
1960 
1961 //----------------------------------------------------------------------
1962 OUString SAL_CALL SvxCustomShape::getShapeType()
1963     throw( uno::RuntimeException )
1964 {
1965     return SvxShape::getShapeType();
1966 }
1967 
1968 //------------------------------------------------------------------1----
1969 awt::Point SAL_CALL SvxCustomShape::getPosition() throw(uno::RuntimeException)
1970 {
1971     OGuard aGuard( Application::GetSolarMutex() );
1972     if ( mpModel && mpObj.is() )
1973     {
1974         SdrAShapeObjGeoData aCustomShapeGeoData;
1975         ((SdrObjCustomShape*)mpObj.get())->SaveGeoData( aCustomShapeGeoData );
1976 
1977         sal_Bool bMirroredX = sal_False;
1978         sal_Bool bMirroredY = sal_False;
1979 
1980         if ( mpObj.is() )
1981         {
1982             bMirroredX = ( ((SdrObjCustomShape*)mpObj.get())->IsMirroredX() );
1983             bMirroredY = ( ((SdrObjCustomShape*)mpObj.get())->IsMirroredY() );
1984         }
1985         // get aRect, this is the unrotated snaprect
1986         Rectangle aRect(((SdrObjCustomShape*)mpObj.get())->GetLogicRect());
1987         Rectangle aRectangle( aRect );
1988 
1989         if ( bMirroredX || bMirroredY )
1990         {   // we have to retrieve the unmirrored rect
1991 
1992             GeoStat aNewGeo( aCustomShapeGeoData.aGeo );
1993             if ( bMirroredX )
1994             {
1995                 Polygon aPol( Rect2Poly( aRect, aNewGeo ) );
1996                 Rectangle aBoundRect( aPol.GetBoundRect() );
1997 
1998                 Point aRef1( ( aBoundRect.Left() + aBoundRect.Right() ) >> 1, aBoundRect.Top() );
1999                 Point aRef2( aRef1.X(), aRef1.Y() + 1000 );
2000                 sal_uInt16 i;
2001                 sal_uInt16 nPntAnz=aPol.GetSize();
2002                 for (i=0; i<nPntAnz; i++)
2003                 {
2004                     MirrorPoint(aPol[i],aRef1,aRef2);
2005                 }
2006                 // Polygon wenden und etwas schieben
2007                 Polygon aPol0(aPol);
2008                 aPol[0]=aPol0[1];
2009                 aPol[1]=aPol0[0];
2010                 aPol[2]=aPol0[3];
2011                 aPol[3]=aPol0[2];
2012                 aPol[4]=aPol0[1];
2013                 Poly2Rect(aPol,aRectangle,aNewGeo);
2014             }
2015             if ( bMirroredY )
2016             {
2017                 Polygon aPol( Rect2Poly( aRectangle, aNewGeo ) );
2018                 Rectangle aBoundRect( aPol.GetBoundRect() );
2019 
2020                 Point aRef1( aBoundRect.Left(), ( aBoundRect.Top() + aBoundRect.Bottom() ) >> 1 );
2021                 Point aRef2( aRef1.X() + 1000, aRef1.Y() );
2022                 sal_uInt16 i;
2023                 sal_uInt16 nPntAnz=aPol.GetSize();
2024                 for (i=0; i<nPntAnz; i++)
2025                 {
2026                     MirrorPoint(aPol[i],aRef1,aRef2);
2027                 }
2028                 // Polygon wenden und etwas schieben
2029                 Polygon aPol0(aPol);
2030                 aPol[0]=aPol0[1];
2031                 aPol[1]=aPol0[0];
2032                 aPol[2]=aPol0[3];
2033                 aPol[3]=aPol0[2];
2034                 aPol[4]=aPol0[1];
2035                 Poly2Rect( aPol, aRectangle, aNewGeo );
2036             }
2037         }
2038         Point aPt( aRectangle.TopLeft() );
2039 
2040         if( mpModel->IsWriter() )
2041             aPt -= mpObj->GetAnchorPos();
2042 
2043         ForceMetricTo100th_mm(aPt);
2044         return ::com::sun::star::awt::Point( aPt.X(), aPt.Y() );
2045     }
2046     else
2047         return SvxShape::getPosition();
2048 }
2049 
2050 //----------------------------------------------------------------------
2051 void SAL_CALL SvxCustomShape::setPosition( const awt::Point& Position ) throw(uno::RuntimeException)
2052 {
2053     SvxShapeText::setPosition(Position);
2054 }
2055 
2056 //----------------------------------------------------------------------
2057 
2058 awt::Size SAL_CALL SvxCustomShape::getSize() throw(uno::RuntimeException)
2059 {
2060     return SvxShapeText::getSize();
2061 }
2062 
2063 //----------------------------------------------------------------------
2064 void SAL_CALL SvxCustomShape::setSize( const awt::Size& rSize )
2065     throw(beans::PropertyVetoException, uno::RuntimeException)
2066 {
2067     SvxShapeText::setSize( rSize );
2068 }
2069 
2070 //----------------------------------------------------------------------
2071 
2072 //----------------------------------------------------------------------
2073 void SAL_CALL SvxCustomShape::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
2074     throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException)
2075 {
2076     OGuard aGuard( Application::GetSolarMutex() );
2077     SdrObject* pObject = mpObj.get();
2078 
2079     sal_Bool bCustomShapeGeometry = pObject && aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CustomShapeGeometry" ) );
2080 
2081     sal_Bool bMirroredX = sal_False;
2082     sal_Bool bMirroredY = sal_False;
2083 
2084     if ( bCustomShapeGeometry )
2085     {
2086         bMirroredX = ( ((SdrObjCustomShape*)pObject)->IsMirroredX() );
2087         bMirroredY = ( ((SdrObjCustomShape*)pObject)->IsMirroredY() );
2088     }
2089 
2090     SvxShape::setPropertyValue( aPropertyName, aValue );
2091 
2092     if ( bCustomShapeGeometry )
2093     {
2094         ((SdrObjCustomShape*)pObject)->MergeDefaultAttributes(0);
2095         Rectangle aRect( pObject->GetSnapRect() );
2096 
2097         // #i38892#
2098         bool bNeedsMirrorX = ((SdrObjCustomShape*)pObject)->IsMirroredX() != bMirroredX;
2099         bool bNeedsMirrorY = ((SdrObjCustomShape*)pObject)->IsMirroredY() != bMirroredY;
2100 
2101         boost::scoped_ptr< SdrGluePointList > pListCopy;
2102         if( bNeedsMirrorX || bNeedsMirrorY )
2103         {
2104             const SdrGluePointList* pList = pObject->GetGluePointList();
2105             if( pList )
2106                 pListCopy.reset( new SdrGluePointList(*pList) );
2107         }
2108 
2109         if ( bNeedsMirrorX )
2110         {
2111             Point aTop( ( aRect.Left() + aRect.Right() ) >> 1, aRect.Top() );
2112             Point aBottom( aTop.X(), aTop.Y() + 1000 );
2113             pObject->NbcMirror( aTop, aBottom );
2114             // NbcMirroring is flipping the current mirror state,
2115             // so we have to set the correct state again
2116             ((SdrObjCustomShape*)pObject)->SetMirroredX( bMirroredX ? sal_False : sal_True );
2117         }
2118         if ( bNeedsMirrorY )
2119         {
2120             Point aLeft( aRect.Left(), ( aRect.Top() + aRect.Bottom() ) >> 1 );
2121             Point aRight( aLeft.X() + 1000, aLeft.Y() );
2122             pObject->NbcMirror( aLeft, aRight );
2123             // NbcMirroring is flipping the current mirror state,
2124             // so we have to set the correct state again
2125             ((SdrObjCustomShape*)pObject)->SetMirroredY( bMirroredY ? sal_False : sal_True );
2126         }
2127 
2128         if( pListCopy )
2129         {
2130             SdrGluePointList* pNewList = const_cast< SdrGluePointList* >( pObject->GetGluePointList() );
2131             if(pNewList)
2132                 *pNewList = *pListCopy;
2133         }
2134     }
2135 }
2136 
2137 bool SvxCustomShape::getPropertyValueImpl( const ::rtl::OUString& rName, const SfxItemPropertySimpleEntry* pProperty, ::com::sun::star::uno::Any& rValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
2138 {
2139     switch( pProperty->nWID )
2140     {
2141     case SDRATTR_ROTATEANGLE:
2142     {
2143         double fAngle = static_cast<SdrObjCustomShape*>(mpObj.get())->GetObjectRotation();
2144         fAngle *= 100;
2145         rValue <<= (sal_Int32)fAngle;
2146         return true;
2147     }
2148     default:
2149         return SvxShape::getPropertyValueImpl( rName, pProperty, rValue );
2150     }
2151 }
2152 //----------------------------------------------------------------------
2153 
2154 void SvxCustomShape::createCustomShapeDefaults( const rtl::OUString& rValueType ) throw (::com::sun::star::uno::RuntimeException)
2155 {
2156     ((SdrObjCustomShape*)mpObj.get())->MergeDefaultAttributes( &rValueType );
2157 }
2158