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