1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <config_features.h>
21 #include <config_feature_desktop.h>
22 
23 #include <com/sun/star/document/EventObject.hpp>
24 #include <com/sun/star/embed/XEmbeddedObject.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <osl/mutex.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <comphelper/classids.hxx>
30 #include <comphelper/sequence.hxx>
31 #include <cppuhelper/supportsservice.hxx>
32 
33 #include <sfx2/objsh.hxx>
34 #include <svx/svdpool.hxx>
35 #include <svx/svdobj.hxx>
36 #include <svx/svdoole2.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/svdmodel.hxx>
39 #include <svx/strings.hrc>
40 #include <svx/svdview.hxx>
41 #include <svx/svdpagv.hxx>
42 #include <svx/svdundo.hxx>
43 #include <svx/unopage.hxx>
44 #include "shapeimpl.hxx"
45 #include <svx/dialmgr.hxx>
46 #include <svx/globl3d.hxx>
47 #include <svx/unoprov.hxx>
48 #include <svx/svdopath.hxx>
49 #include <svx/unoapi.hxx>
50 #include <svx/svdomeas.hxx>
51 #include <svx/extrud3d.hxx>
52 #include <svx/lathe3d.hxx>
53 #include <svx/scene3d.hxx>
54 #include <vcl/svapp.hxx>
55 #include <tools/diagnose_ex.h>
56 #include <tools/globname.hxx>
57 #include <sal/log.hxx>
58 
59 using namespace ::cppu;
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::lang;
63 using namespace ::com::sun::star::container;
64 using namespace ::com::sun::star::drawing;
65 
66 UNO3_GETIMPLEMENTATION_IMPL( SvxDrawPage );
67 
SvxDrawPage(SdrPage * pInPage)68 SvxDrawPage::SvxDrawPage(SdrPage* pInPage) // TTTT should be reference
69 :   mrBHelper(getMutex())
70     ,mpPage(pInPage)
71     ,mpModel(&pInPage->getSdrModelFromSdrPage())  // register at broadcaster
72     ,mpView(new SdrView(pInPage->getSdrModelFromSdrPage())) // create (hidden) view
73 {
74     mpView->SetDesignMode();
75 }
76 
~SvxDrawPage()77 SvxDrawPage::~SvxDrawPage() throw()
78 {
79     if( !mrBHelper.bDisposed )
80     {
81         assert(!"SvxDrawPage must be disposed!");
82         acquire();
83         dispose();
84     }
85 }
86 
87 // XInterface
release()88 void SvxDrawPage::release() throw()
89 {
90     OWeakAggObject::release();
91 }
92 
93 // XComponent
disposing()94 void SvxDrawPage::disposing() throw()
95 {
96     if( mpModel )
97     {
98         mpModel = nullptr;
99     }
100 
101     mpView.reset();
102     mpPage = nullptr;
103 }
104 
105 // XComponent
dispose()106 void SvxDrawPage::dispose()
107 {
108     SolarMutexGuard aSolarGuard;
109 
110     // An frequently programming error is to release the last
111     // reference to this object in the disposing message.
112     // Make it robust, hold a self Reference.
113     uno::Reference< lang::XComponent > xSelf( this );
114 
115     // Guard dispose against multiple threading
116     // Remark: It is an error to call dispose more than once
117     bool bDoDispose = false;
118     {
119         osl::MutexGuard aGuard( mrBHelper.rMutex );
120         if( !mrBHelper.bDisposed && !mrBHelper.bInDispose )
121         {
122             // only one call go into this section
123             mrBHelper.bInDispose = true;
124             bDoDispose = true;
125         }
126     }
127 
128     // Do not hold the mutex because we are broadcasting
129     if( bDoDispose )
130     {
131         // Create an event with this as sender
132         try
133         {
134             uno::Reference< uno::XInterface > xSource( uno::Reference< uno::XInterface >::query( static_cast<lang::XComponent *>(this) ) );
135             css::document::EventObject aEvt;
136             aEvt.Source = xSource;
137             // inform all listeners to release this object
138             // The listener container are automatically cleared
139             mrBHelper.aLC.disposeAndClear( aEvt );
140             // notify subclasses to do their dispose
141             disposing();
142         }
143         catch(const css::uno::Exception&)
144         {
145             // catch exception and throw again but signal that
146             // the object was disposed. Dispose should be called
147             // only once.
148             osl::MutexGuard aGuard( mrBHelper.rMutex );
149             mrBHelper.bDisposed = true;
150             mrBHelper.bInDispose = false;
151             throw;
152         }
153 
154         osl::MutexGuard aGuard( mrBHelper.rMutex );
155         mrBHelper.bDisposed = true;
156         mrBHelper.bInDispose = false;
157     }
158 
159 }
160 
addEventListener(const css::uno::Reference<css::lang::XEventListener> & aListener)161 void SAL_CALL SvxDrawPage::addEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
162 {
163     SolarMutexGuard aGuard;
164 
165     if( mpModel == nullptr )
166         throw lang::DisposedException();
167 
168     mrBHelper.addListener( cppu::UnoType<decltype(aListener)>::get() , aListener );
169 }
170 
removeEventListener(const css::uno::Reference<css::lang::XEventListener> & aListener)171 void SAL_CALL SvxDrawPage::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener )
172 {
173     SolarMutexGuard aGuard;
174 
175     if( mpModel == nullptr )
176         throw lang::DisposedException();
177 
178     mrBHelper.removeListener( cppu::UnoType<decltype(aListener)>::get() , aListener );
179 }
180 
add(const uno::Reference<drawing::XShape> & xShape)181 void SAL_CALL SvxDrawPage::add( const uno::Reference< drawing::XShape >& xShape )
182 {
183     SolarMutexGuard aGuard;
184 
185     if ( ( mpModel == nullptr ) || ( mpPage == nullptr ) )
186         throw lang::DisposedException();
187 
188     SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
189 
190     if( nullptr == pShape )
191         return;
192 
193     SdrObject *pObj = pShape->GetSdrObject();
194     bool bNeededToClone(false);
195 
196     if(nullptr != pObj && &pObj->getSdrModelFromSdrObject() != &mpPage->getSdrModelFromSdrPage())
197     {
198         // TTTT UNO API tries to add an existing SvxShape to this SvxDrawPage,
199         // but these use different SdrModels. It was possible before to completely
200         // 'change' a SdrObject to another SdrModel (including dangerous MigrateItemPool
201         // stuff), but is no longer. We need to Clone the SdrObject to the target model
202         // and ::Create a new SvxShape (set SdrObject there, take obver values, ...)
203         SdrObject* pClonedSdrShape(pObj->CloneSdrObject(mpPage->getSdrModelFromSdrPage()));
204         pObj->setUnoShape(nullptr);
205         pClonedSdrShape->setUnoShape(xShape);
206         // pShape->InvalidateSdrObject();
207         // pShape->Create(pClonedSdrShape, this);
208         SdrObject::Free(pObj);
209         pObj = pClonedSdrShape;
210         bNeededToClone = true;
211     }
212 
213     if(!pObj)
214     {
215         pObj = CreateSdrObject( xShape );
216         ENSURE_OR_RETURN_VOID( pObj != nullptr, "SvxDrawPage::add: no SdrObject was created!" );
217     }
218     else if ( !pObj->IsInserted() )
219     {
220         mpPage->InsertObject( pObj );
221 
222         if(bNeededToClone)
223         {
224             // TTTT Unfortunately in SdrObject::SetPage (see there) the
225             // xShape/UnoShape at the newly cloned SDrObject is *removed* again,
226             // so re-set it here, the caller *may need it* (e.g. Writer)
227             uno::Reference< uno::XInterface > xShapeCheck(pObj->getWeakUnoShape());
228 
229             if( !xShapeCheck.is() )
230             {
231                 pObj->setUnoShape(xShape);
232             }
233         }
234     }
235 
236     pShape->Create( pObj, this );
237     OSL_ENSURE( pShape->GetSdrObject() == pObj, "SvxDrawPage::add: shape does not know about its newly created SdrObject!" );
238 
239     if ( !pObj->IsInserted() )
240     {
241         mpPage->InsertObject( pObj );
242     }
243 
244     mpModel->SetChanged();
245 }
246 
addTop(const uno::Reference<drawing::XShape> & xShape)247 void SAL_CALL SvxDrawPage::addTop( const uno::Reference< drawing::XShape >& xShape )
248 {
249     add(xShape);
250 }
251 
addBottom(const uno::Reference<drawing::XShape> & xShape)252 void SAL_CALL SvxDrawPage::addBottom( const uno::Reference< drawing::XShape >& xShape )
253 {
254     SolarMutexGuard aGuard;
255 
256     if ( ( mpModel == nullptr ) || ( mpPage == nullptr ) )
257         throw lang::DisposedException();
258 
259     SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
260 
261     if( nullptr == pShape )
262         return;
263 
264     SdrObject *pObj = pShape->GetSdrObject();
265 
266     if(!pObj)
267     {
268         pObj = CreateSdrObject( xShape, true );
269         ENSURE_OR_RETURN_VOID( pObj != nullptr, "SvxDrawPage::add: no SdrObject was created!" );
270     }
271     else if ( !pObj->IsInserted() )
272     {
273         mpPage->InsertObject( pObj, 0 );
274     }
275 
276     pShape->Create( pObj, this );
277     OSL_ENSURE( pShape->GetSdrObject() == pObj, "SvxDrawPage::add: shape does not know about its newly created SdrObject!" );
278 
279     if ( !pObj->IsInserted() )
280     {
281         mpPage->InsertObject( pObj, 0 );
282     }
283 
284     mpModel->SetChanged();
285 }
286 
remove(const Reference<drawing::XShape> & xShape)287 void SAL_CALL SvxDrawPage::remove( const Reference< drawing::XShape >& xShape )
288 {
289     SolarMutexGuard aGuard;
290 
291     if( (mpModel == nullptr) || (mpPage == nullptr) )
292         throw lang::DisposedException();
293 
294     SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
295 
296     if (pShape)
297     {
298         SdrObject* pObj = pShape->GetSdrObject();
299         if (pObj)
300         {
301             // remove SdrObject from page
302             const size_t nCount = mpPage->GetObjCount();
303             for( size_t nNum = 0; nNum < nCount; ++nNum )
304             {
305                 if(mpPage->GetObj(nNum) == pObj)
306                 {
307                     const bool bUndoEnabled = mpModel->IsUndoEnabled();
308 
309                     if (bUndoEnabled)
310                     {
311                         mpModel->BegUndo(SvxResId(STR_EditDelete),
312                             pObj->TakeObjNameSingul(), SdrRepeatFunc::Delete);
313 
314                         mpModel->AddUndo(mpModel->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
315                     }
316 
317                     OSL_VERIFY( mpPage->RemoveObject( nNum ) == pObj );
318 
319                     if (!bUndoEnabled)
320                         SdrObject::Free(pObj);
321 
322                     if (bUndoEnabled)
323                         mpModel->EndUndo();
324 
325                     break;
326                 }
327             }
328         }
329     }
330 
331     mpModel->SetChanged();
332 }
333 
sort(const css::uno::Sequence<sal_Int32> & sortOrder)334 void SvxDrawPage::sort( const css::uno::Sequence< sal_Int32 >& sortOrder )
335 {
336     auto newOrder = comphelper::sequenceToContainer<std::vector<sal_Int32>>(sortOrder);
337     mpPage->sort(newOrder);
338 }
339 
340 // css::container::XIndexAccess
getCount()341 sal_Int32 SAL_CALL SvxDrawPage::getCount()
342 {
343     SolarMutexGuard aGuard;
344 
345     if( (mpModel == nullptr) || (mpPage == nullptr) )
346         throw lang::DisposedException();
347 
348     return static_cast<sal_Int32>( mpPage->GetObjCount() );
349 }
350 
getByIndex(sal_Int32 Index)351 uno::Any SAL_CALL SvxDrawPage::getByIndex( sal_Int32 Index )
352 {
353     SolarMutexGuard aGuard;
354 
355     if( (mpModel == nullptr) || (mpPage == nullptr) )
356         throw lang::DisposedException("Model or Page was already disposed!");
357 
358     if ( Index < 0 || static_cast<size_t>(Index) >= mpPage->GetObjCount() )
359         throw lang::IndexOutOfBoundsException("Index (" + OUString::number(Index)
360                                               + ") needs to be a positive integer smaller than the shape count ("
361                                               + OUString::number(mpPage->GetObjCount()) + ")!");
362 
363     SdrObject* pObj = mpPage->GetObj( Index );
364     if( pObj == nullptr )
365         throw uno::RuntimeException("Runtime exception thrown while getting a ref to the SdrObject at index: "
366                                     + OUString::number(Index));
367 
368 
369     return makeAny(Reference< drawing::XShape >( pObj->getUnoShape(), uno::UNO_QUERY ));
370 }
371 
372 // css::container::XElementAccess
getElementType()373 uno::Type SAL_CALL SvxDrawPage::getElementType()
374 {
375     return cppu::UnoType<drawing::XShape>::get();
376 }
377 
hasElements()378 sal_Bool SAL_CALL SvxDrawPage::hasElements()
379 {
380     SolarMutexGuard aGuard;
381 
382     if( (mpModel == nullptr) || (mpPage == nullptr) )
383         throw lang::DisposedException();
384 
385     return mpPage && mpPage->GetObjCount()>0;
386 }
387 
388 namespace
389 {
lcl_markSdrObjectOfShape(const Reference<drawing::XShape> & _rxShape,SdrView & _rView,SdrPageView & _rPageView)390     void lcl_markSdrObjectOfShape( const Reference< drawing::XShape >& _rxShape, SdrView& _rView, SdrPageView& _rPageView )
391     {
392         SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( _rxShape );
393         if ( !pShape )
394             return;
395 
396         SdrObject* pObj = pShape->GetSdrObject();
397         if ( !pObj )
398             return;
399 
400         _rView.MarkObj( pObj, &_rPageView );
401     }
402 }
403 
404 // ATTENTION: SelectObjectsInView selects the css::drawing::Shapes
405 // only in the given SdrPageView. It hasn't to be the visible SdrPageView.
SelectObjectsInView(const Reference<drawing::XShapes> & aShapes,SdrPageView * pPageView)406 void SvxDrawPage::SelectObjectsInView( const Reference< drawing::XShapes > & aShapes, SdrPageView* pPageView ) throw ()
407 {
408     SAL_WARN_IF(!pPageView, "svx", "SdrPageView is NULL!");
409     SAL_WARN_IF(!mpView, "svx", "SdrView is NULL!");
410 
411     if(pPageView!=nullptr && mpView!=nullptr)
412     {
413         mpView->UnmarkAllObj( pPageView );
414 
415         long nCount = aShapes->getCount();
416         for( long i = 0; i < nCount; i++ )
417         {
418             uno::Any aAny( aShapes->getByIndex(i) );
419             Reference< drawing::XShape > xShape;
420             if( aAny >>= xShape )
421                 lcl_markSdrObjectOfShape( xShape, *mpView, *pPageView );
422         }
423     }
424 }
425 
426 // ATTENTION: SelectObjectInView selects the shape only in the given SdrPageView.
427 // It hasn't to be the visible SdrPageView.
SelectObjectInView(const Reference<drawing::XShape> & xShape,SdrPageView * pPageView)428 void SvxDrawPage::SelectObjectInView( const Reference< drawing::XShape > & xShape, SdrPageView* pPageView ) throw()
429 {
430     SAL_WARN_IF(!pPageView, "svx", "SdrPageView is NULL!");
431     SAL_WARN_IF(!mpView, "svx", "SdrView is NULL!");
432 
433     if(pPageView!=nullptr && mpView != nullptr)
434     {
435         mpView->UnmarkAllObj( pPageView );
436         lcl_markSdrObjectOfShape( xShape, *mpView, *pPageView );
437     }
438 }
439 
group(const Reference<drawing::XShapes> & xShapes)440 Reference< drawing::XShapeGroup > SAL_CALL SvxDrawPage::group( const Reference< drawing::XShapes >& xShapes )
441 {
442     SolarMutexGuard aGuard;
443 
444     if( (mpModel == nullptr) || (mpPage == nullptr) )
445         throw lang::DisposedException();
446 
447     SAL_WARN_IF(!mpPage , "svx", "SdrPage is NULL!");
448     SAL_WARN_IF(!mpView, "svx", "SdrView is NULL!");
449 
450     Reference< css::drawing::XShapeGroup >  xShapeGroup;
451     if(mpPage==nullptr||mpView==nullptr||!xShapes.is())
452         return xShapeGroup;
453 
454     SdrPageView* pPageView = mpView->ShowSdrPage( mpPage );
455 
456     SelectObjectsInView( xShapes, pPageView );
457 
458     mpView->GroupMarked();
459 
460     mpView->AdjustMarkHdl();
461     const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
462     if( rMarkList.GetMarkCount() == 1 )
463     {
464         SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
465         if( pObj )
466              xShapeGroup.set( pObj->getUnoShape(), UNO_QUERY );
467     }
468 
469     mpView->HideSdrPage();
470 
471     if( mpModel )
472         mpModel->SetChanged();
473 
474     return xShapeGroup;
475 }
476 
ungroup(const Reference<drawing::XShapeGroup> & aGroup)477 void SAL_CALL SvxDrawPage::ungroup( const Reference< drawing::XShapeGroup >& aGroup )
478 {
479     SolarMutexGuard aGuard;
480 
481     if( (mpModel == nullptr) || (mpPage == nullptr) )
482         throw lang::DisposedException();
483 
484     SAL_WARN_IF(!mpPage, "svx", "SdrPage is NULL!");
485     SAL_WARN_IF(!mpView, "svx", "SdrView is NULL!");
486 
487     if(mpPage==nullptr||mpView==nullptr||!aGroup.is())
488         return;
489 
490     SdrPageView* pPageView = mpView->ShowSdrPage( mpPage );
491 
492     SelectObjectInView( aGroup, pPageView );
493     mpView->UnGroupMarked();
494 
495     mpView->HideSdrPage();
496 
497     if( mpModel )
498         mpModel->SetChanged();
499 }
500 
CreateSdrObject_(const Reference<drawing::XShape> & xShape)501 SdrObject* SvxDrawPage::CreateSdrObject_(const Reference< drawing::XShape > & xShape)
502 {
503     sal_uInt16 nType = 0;
504     SdrInventor nInventor;
505 
506     GetTypeAndInventor( nType, nInventor, xShape->getShapeType() );
507     if (!nType)
508         return nullptr;
509 
510     awt::Size aSize = xShape->getSize();
511     aSize.Width += 1;
512     aSize.Height += 1;
513     awt::Point aPos = xShape->getPosition();
514     tools::Rectangle aRect( Point( aPos.X, aPos.Y ), Size( aSize.Width, aSize.Height ) );
515 
516     SdrObject* pNewObj = SdrObjFactory::MakeNewObject(
517         *mpModel,
518         nInventor,
519         nType,
520         &aRect);
521 
522     if (!pNewObj)
523         return nullptr;
524 
525     if( auto pScene = dynamic_cast<E3dScene* >(pNewObj) )
526     {
527         // initialise scene
528 
529         double fW = static_cast<double>(aSize.Width);
530         double fH = static_cast<double>(aSize.Height);
531 
532         Camera3D aCam(pScene->GetCamera());
533         aCam.SetAutoAdjustProjection(false);
534         aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
535         basegfx::B3DPoint aLookAt;
536         basegfx::B3DPoint aCamPos(0.0, 0.0, 10000.0);
537         aCam.SetPosAndLookAt(aCamPos, aLookAt);
538         aCam.SetFocalLength(100.0);
539         pScene->SetCamera(aCam);
540 
541         pScene->SetRectsDirty();
542     }
543     else if(dynamic_cast<const E3dExtrudeObj* >(pNewObj) !=  nullptr)
544     {
545         E3dExtrudeObj* pObj = static_cast<E3dExtrudeObj*>(pNewObj);
546         basegfx::B2DPolygon aNewPolygon;
547         aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0));
548         aNewPolygon.append(basegfx::B2DPoint(0.0, 1.0));
549         aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0));
550         aNewPolygon.setClosed(true);
551         pObj->SetExtrudePolygon(basegfx::B2DPolyPolygon(aNewPolygon));
552 
553         // #107245# pObj->SetExtrudeCharacterMode(sal_True);
554         pObj->SetMergedItem(Svx3DCharacterModeItem(true));
555     }
556     else if(dynamic_cast<const E3dLatheObj* >(pNewObj) !=  nullptr)
557     {
558         E3dLatheObj* pObj = static_cast<E3dLatheObj*>(pNewObj);
559         basegfx::B2DPolygon aNewPolygon;
560         aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0));
561         aNewPolygon.append(basegfx::B2DPoint(0.0, 1.0));
562         aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0));
563         aNewPolygon.setClosed(true);
564         pObj->SetPolyPoly2D(basegfx::B2DPolyPolygon(aNewPolygon));
565 
566         // #107245# pObj->SetLatheCharacterMode(sal_True);
567         pObj->SetMergedItem(Svx3DCharacterModeItem(true));
568     }
569 
570     return pNewObj;
571 }
572 
GetTypeAndInventor(sal_uInt16 & rType,SdrInventor & rInventor,const OUString & aName)573 void SvxDrawPage::GetTypeAndInventor( sal_uInt16& rType, SdrInventor& rInventor, const OUString& aName ) throw()
574 {
575     sal_uInt32 nTempType = UHashMap::getId( aName );
576 
577     if( nTempType == UHASHMAP_NOTFOUND )
578     {
579         if( aName == "com.sun.star.drawing.TableShape" ||
580             aName == "com.sun.star.presentation.TableShape" )
581         {
582             rInventor = SdrInventor::Default;
583             rType = OBJ_TABLE;
584         }
585 #if HAVE_FEATURE_AVMEDIA
586         else if ( aName == "com.sun.star.presentation.MediaShape" )
587         {
588             rInventor = SdrInventor::Default;
589             rType = OBJ_MEDIA;
590         }
591 #endif
592     }
593     else if(nTempType & E3D_INVENTOR_FLAG)
594     {
595         rInventor = SdrInventor::E3d;
596         rType = static_cast<sal_uInt16>(nTempType & ~E3D_INVENTOR_FLAG);
597     }
598     else
599     {
600         rInventor = SdrInventor::Default;
601         rType = static_cast<sal_uInt16>(nTempType);
602 
603         switch( rType )
604         {
605             case OBJ_FRAME:
606             case OBJ_OLE2_PLUGIN:
607             case OBJ_OLE2_APPLET:
608                 rType = OBJ_OLE2;
609                 break;
610         }
611     }
612 }
613 
CreateShapeByTypeAndInventor(sal_uInt16 nType,SdrInventor nInventor,SdrObject * pObj,SvxDrawPage * mpPage,OUString const & referer)614 SvxShape* SvxDrawPage::CreateShapeByTypeAndInventor( sal_uInt16 nType, SdrInventor nInventor, SdrObject *pObj, SvxDrawPage *mpPage, OUString const & referer )
615 {
616 #if !HAVE_FEATURE_DESKTOP
617     (void) referer;
618 #endif
619     SvxShape* pRet = nullptr;
620 #if !HAVE_FEATURE_DESKTOP
621     (void)referer;
622 #endif
623 
624     switch( nInventor )
625     {
626         case SdrInventor::E3d:
627         {
628             switch( nType )
629             {
630                 case E3D_SCENE_ID :
631                     pRet = new Svx3DSceneObject( pObj, mpPage );
632                     break;
633                 case E3D_CUBEOBJ_ID :
634                     pRet = new Svx3DCubeObject( pObj );
635                     break;
636                 case E3D_SPHEREOBJ_ID :
637                     pRet = new Svx3DSphereObject( pObj );
638                     break;
639                 case E3D_LATHEOBJ_ID :
640                     pRet = new Svx3DLatheObject( pObj );
641                     break;
642                 case E3D_EXTRUDEOBJ_ID :
643                     pRet = new Svx3DExtrudeObject( pObj );
644                     break;
645                 case E3D_POLYGONOBJ_ID :
646                     pRet = new Svx3DPolygonObject( pObj );
647                     break;
648                 default: // unknown 3D-object on page
649                     pRet = new SvxShape( pObj );
650                     break;
651             }
652             break;
653         }
654         case SdrInventor::Default:
655         {
656             switch( nType )
657             {
658                 case OBJ_GRUP:
659                     pRet = new SvxShapeGroup( pObj, mpPage );
660                     break;
661                 case OBJ_LINE:
662                     pRet = new SvxShapePolyPolygon( pObj );
663                     break;
664                 case OBJ_RECT:
665                     pRet = new SvxShapeRect( pObj );
666                     break;
667                 case OBJ_CIRC:
668                 case OBJ_SECT:
669                 case OBJ_CARC:
670                 case OBJ_CCUT:
671                     pRet = new SvxShapeCircle( pObj );
672                     break;
673                 case OBJ_POLY:
674                     pRet = new SvxShapePolyPolygon( pObj );
675                     break;
676                 case OBJ_PLIN:
677                     pRet = new SvxShapePolyPolygon( pObj );
678                     break;
679                 case OBJ_SPLNLINE:
680                 case OBJ_PATHLINE:
681                     pRet = new SvxShapePolyPolygon( pObj );
682                     break;
683                 case OBJ_SPLNFILL:
684                 case OBJ_PATHFILL:
685                     pRet = new SvxShapePolyPolygon( pObj );
686                     break;
687                 case OBJ_FREELINE:
688                     pRet = new SvxShapePolyPolygon( pObj );
689                     break;
690                 case OBJ_FREEFILL:
691                     pRet = new SvxShapePolyPolygon( pObj );
692                     break;
693                 case OBJ_CAPTION:
694                     pRet = new SvxShapeCaption( pObj );
695                     break;
696                 case OBJ_TITLETEXT:
697                 case OBJ_OUTLINETEXT:
698                 case OBJ_TEXT:
699                     pRet = new SvxShapeText( pObj );
700                     break;
701                 case OBJ_GRAF:
702                     pRet = new SvxGraphicObject( pObj );
703                     break;
704                 case OBJ_FRAME:
705                     pRet = new SvxFrameShape( pObj );
706                     break;
707                 case OBJ_OLE2_APPLET:
708                     pRet = new SvxAppletShape( pObj );
709                     break;
710                 case OBJ_OLE2_PLUGIN:
711                     pRet = new SvxPluginShape( pObj );
712                     break;
713                  case OBJ_OLE2:
714                      {
715                         if( pObj && !pObj->IsEmptyPresObj() && mpPage )
716                         {
717                             SdrPage* pSdrPage = mpPage->GetSdrPage();
718                             if( pSdrPage )
719                             {
720                                 SdrModel& rSdrModel(pSdrPage->getSdrModelFromSdrPage());
721                                 ::comphelper::IEmbeddedHelper *pPersist = rSdrModel.GetPersist();
722 
723                                 if( pPersist )
724                                 {
725                                     uno::Reference < embed::XEmbeddedObject > xObject = pPersist->getEmbeddedObjectContainer().
726                                             GetEmbeddedObject( static_cast< SdrOle2Obj* >( pObj )->GetPersistName() );
727 
728                                     // TODO CL->KA: Why is this not working anymore?
729                                     if( xObject.is() )
730                                     {
731                                         SvGlobalName aClassId( xObject->getClassID() );
732 
733                                         const SvGlobalName aAppletClassId( SO3_APPLET_CLASSID );
734                                         const SvGlobalName aPluginClassId( SO3_PLUGIN_CLASSID );
735                                         const SvGlobalName aIFrameClassId( SO3_IFRAME_CLASSID );
736 
737                                         if( aPluginClassId == aClassId )
738                                         {
739                                             pRet = new SvxPluginShape( pObj );
740                                             nType = OBJ_OLE2_PLUGIN;
741                                         }
742                                         else if( aAppletClassId == aClassId )
743                                         {
744                                             pRet = new SvxAppletShape( pObj );
745                                             nType = OBJ_OLE2_APPLET;
746                                         }
747                                         else if( aIFrameClassId == aClassId )
748                                         {
749                                             pRet = new SvxFrameShape( pObj );
750                                             nType = OBJ_FRAME;
751                                         }
752                                     }
753                                 }
754                             }
755                         }
756                         if( pRet == nullptr )
757                         {
758                             SvxUnoPropertyMapProvider& rSvxMapProvider = getSvxMapProvider();
759                             pRet = new SvxOle2Shape( pObj, rSvxMapProvider.GetMap(SVXMAP_OLE2),  rSvxMapProvider.GetPropertySet(SVXMAP_OLE2, SdrObject::GetGlobalDrawObjectItemPool()) );
760                         }
761                      }
762                     break;
763                 case OBJ_EDGE:
764                     pRet = new SvxShapeConnector( pObj );
765                     break;
766                 case OBJ_PATHPOLY:
767                     pRet = new SvxShapePolyPolygon( pObj );
768                     break;
769                 case OBJ_PATHPLIN:
770                     pRet = new SvxShapePolyPolygon( pObj );
771                     break;
772                 case OBJ_PAGE:
773                 {
774                     SvxUnoPropertyMapProvider& rSvxMapProvider = getSvxMapProvider();
775                     pRet = new SvxShape( pObj, rSvxMapProvider.GetMap(SVXMAP_PAGE),  rSvxMapProvider.GetPropertySet(SVXMAP_PAGE, SdrObject::GetGlobalDrawObjectItemPool()) );
776                 }
777                     break;
778                 case OBJ_MEASURE:
779                     pRet = new SvxShapeDimensioning( pObj );
780                     break;
781                 case OBJ_UNO:
782                     pRet = new SvxShapeControl( pObj );
783                     break;
784                 case OBJ_CUSTOMSHAPE:
785                     pRet = new SvxCustomShape( pObj );
786                     break;
787 #if HAVE_FEATURE_DESKTOP
788                 case OBJ_MEDIA:
789                     pRet = new SvxMediaShape( pObj, referer );
790                     break;
791 #endif
792                 case OBJ_TABLE:
793                     pRet = new SvxTableShape( pObj );
794                     break;
795                 default: // unknown 2D-object on page
796                     assert(false && "Not implemented Starone-Shape created");
797                     pRet = new SvxShapeText( pObj );
798                     break;
799             }
800             break;
801         }
802         default: // unknown inventor
803         {
804             assert(false && "Unknown Inventor in SvxDrawPage::CreateShape()");
805             break;
806         }
807     }
808 
809     if(pRet)
810     {
811         sal_uInt32 nObjId = nType;
812 
813         if( nInventor == SdrInventor::E3d )
814             nObjId |= E3D_INVENTOR_FLAG;
815 
816         switch(nObjId)
817         {
818         case OBJ_CCUT:          // segment of circle
819         case OBJ_CARC:          // arc of circle
820         case OBJ_SECT:          // sector
821             nObjId = OBJ_CIRC;
822             break;
823 
824         case OBJ_TITLETEXT:
825         case OBJ_OUTLINETEXT:
826             nObjId = OBJ_TEXT;
827             break;
828         }
829 
830         pRet->setShapeKind(nObjId);
831     }
832 
833     return pRet;
834 }
835 
CreateShape(SdrObject * pObj) const836 Reference< drawing::XShape >  SvxDrawPage::CreateShape( SdrObject *pObj ) const
837 {
838     Reference< drawing::XShape > xShape( CreateShapeByTypeAndInventor(pObj->GetObjIdentifier(),
839                                               pObj->GetObjInventor(),
840                                               pObj,
841                                               const_cast<SvxDrawPage*>(this)));
842     return xShape;
843 }
844 
CreateSdrObject(const Reference<drawing::XShape> & xShape,bool bBeginning)845 SdrObject *SvxDrawPage::CreateSdrObject( const Reference< drawing::XShape > & xShape, bool bBeginning ) throw()
846 {
847     SdrObject* pObj = CreateSdrObject_( xShape );
848     if( pObj)
849     {
850         if ( !pObj->IsInserted() && !pObj->IsDoNotInsertIntoPageAutomatically() )
851         {
852             if(bBeginning)
853                 mpPage->InsertObject( pObj, 0 );
854             else
855                 mpPage->InsertObject( pObj );
856         }
857     }
858 
859     return pObj;
860 }
861 
862 // css::lang::XServiceInfo
getImplementationName()863 OUString SAL_CALL SvxDrawPage::getImplementationName()
864 {
865     return "SvxDrawPage";
866 }
867 
supportsService(const OUString & ServiceName)868 sal_Bool SAL_CALL SvxDrawPage::supportsService( const OUString& ServiceName )
869 {
870     return cppu::supportsService( this, ServiceName );
871 }
872 
getSupportedServiceNames()873 uno::Sequence< OUString > SAL_CALL SvxDrawPage::getSupportedServiceNames()
874 {
875     uno::Sequence<OUString> aSeq { "com.sun.star.drawing.ShapeCollection" };
876     return aSeq;
877 }
878 
CreateSvxShapeByTypeAndInventor(sal_uInt16 nType,SdrInventor nInventor,OUString const & referer)879 SvxShape* CreateSvxShapeByTypeAndInventor(sal_uInt16 nType, SdrInventor nInventor, OUString const & referer)
880 {
881     return SvxDrawPage::CreateShapeByTypeAndInventor( nType, nInventor, nullptr, nullptr, referer );
882 }
883 
884 /** returns a StarOffice API wrapper for the given SdrPage */
GetXDrawPageForSdrPage(SdrPage * pPage)885 uno::Reference< drawing::XDrawPage > GetXDrawPageForSdrPage( SdrPage* pPage ) throw ()
886 {
887     if(pPage)
888     {
889         uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
890 
891         return xDrawPage;
892     }
893 
894     return uno::Reference< drawing::XDrawPage >();
895 }
896 
897 /** returns the SdrObject from the given StarOffice API wrapper */
GetSdrPageFromXDrawPage(const uno::Reference<drawing::XDrawPage> & xDrawPage)898 SdrPage* GetSdrPageFromXDrawPage( const uno::Reference< drawing::XDrawPage >& xDrawPage ) throw()
899 {
900     if(xDrawPage.is())
901     {
902         SvxDrawPage* pDrawPage = comphelper::getUnoTunnelImplementation<SvxDrawPage>( xDrawPage );
903 
904         if(pDrawPage)
905         {
906             return pDrawPage->GetSdrPage();
907         }
908     }
909 
910     return nullptr;
911 }
912 
913 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
914