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