bump product version to 6.4.0.3
[LibreOffice.git] / sd / source / ui / unoidl / unomodel.cxx
blob6f7510488a30abe749f96a9c0d412304c6d97abf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
21 #include <boost/property_tree/json_parser.hpp>
23 #include <com/sun/star/presentation/XPresentation2.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
26 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
28 #include <com/sun/star/lang/Locale.hpp>
29 #include <com/sun/star/awt/XDevice.hpp>
30 #include <com/sun/star/document/IndexedPropertyValues.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
33 #include <com/sun/star/embed/Aspects.hpp>
35 #include <comphelper/lok.hxx>
36 #include <comphelper/sequence.hxx>
37 #include <comphelper/servicehelper.hxx>
38 #include <cppuhelper/supportsservice.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <comphelper/profilezone.hxx>
42 #include <sal/log.hxx>
43 #include <editeng/unofield.hxx>
44 #include <notifydocumentevent.hxx>
45 #include <unomodel.hxx>
46 #include "unopool.hxx"
47 #include <sfx2/lokhelper.hxx>
48 #include <vcl/svapp.hxx>
49 #include <vcl/settings.hxx>
50 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
52 #include <editeng/UnoForbiddenCharsTable.hxx>
53 #include <svx/svdoutl.hxx>
54 #include <o3tl/safeint.hxx>
55 #include <svx/UnoNamespaceMap.hxx>
56 #include <svx/svdlayer.hxx>
57 #include <svx/svdsob.hxx>
58 #include <svx/svdundo.hxx>
59 #include <svx/unoapi.hxx>
60 #include <svx/unofill.hxx>
61 #include <editeng/flditem.hxx>
62 #include <editeng/fontitem.hxx>
63 #include <toolkit/awt/vclxdevice.hxx>
64 #include <svx/svdpool.hxx>
65 #include <svx/svdpagv.hxx>
66 #include <svtools/unoimap.hxx>
67 #include <svx/unoshape.hxx>
68 #include <editeng/unonrule.hxx>
69 #include <editeng/eeitem.hxx>
70 #include <unotools/datetime.hxx>
71 #include <unotools/saveopt.hxx>
72 #include <xmloff/autolayout.hxx>
74 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
75 #include <svx/xmleohlp.hxx>
76 #include <svx/xmlgrhlp.hxx>
77 #include <DrawDocShell.hxx>
78 #include <ViewShellBase.hxx>
79 #include "UnoDocumentSettings.hxx"
81 #include <Annotation.hxx>
82 #include <drawdoc.hxx>
83 #include <sdmod.hxx>
84 #include <sdresid.hxx>
85 #include <sdpage.hxx>
87 #include <strings.hrc>
88 #include <strings.hxx>
89 #include "unolayer.hxx"
90 #include <unopage.hxx>
91 #include "unocpres.hxx"
92 #include "unoobj.hxx"
93 #include <stlpool.hxx>
94 #include "unopback.hxx"
95 #include <unokywds.hxx>
97 #include <FrameView.hxx>
98 #include <ClientView.hxx>
99 #include <DrawViewShell.hxx>
100 #include <ViewShell.hxx>
101 #include <Window.hxx>
102 #include <optsitem.hxx>
104 #include <vcl/pdfextoutdevdata.hxx>
105 #include <com/sun/star/presentation/AnimationSpeed.hpp>
106 #include <com/sun/star/presentation/ClickAction.hpp>
107 #include <svx/sdr/contact/viewobjectcontact.hxx>
108 #include <svx/sdr/contact/viewcontact.hxx>
109 #include <svx/sdr/contact/displayinfo.hxx>
111 #include <com/sun/star/office/XAnnotation.hpp>
112 #include <com/sun/star/office/XAnnotationAccess.hpp>
113 #include <com/sun/star/office/XAnnotationEnumeration.hpp>
114 #include <com/sun/star/geometry/RealPoint2D.hpp>
115 #include <com/sun/star/util/DateTime.hpp>
117 #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
119 #include <sfx2/lokcharthelper.hxx>
120 #include <tools/debug.hxx>
121 #include <tools/diagnose_ex.h>
123 #define TWIPS_PER_PIXEL 15
125 using namespace ::cppu;
126 using namespace ::com::sun::star;
127 using namespace ::sd;
129 class SdUnoForbiddenCharsTable : public SvxUnoForbiddenCharsTable,
130 public SfxListener
132 public:
133 explicit SdUnoForbiddenCharsTable(SdrModel* pModel);
134 virtual ~SdUnoForbiddenCharsTable() override;
136 // SfxListener
137 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) throw () override;
138 protected:
139 virtual void onChange() override;
141 private:
142 SdrModel* mpModel;
145 SdUnoForbiddenCharsTable::SdUnoForbiddenCharsTable( SdrModel* pModel )
146 : SvxUnoForbiddenCharsTable( pModel->GetForbiddenCharsTable() ), mpModel( pModel )
148 StartListening( *pModel );
151 void SdUnoForbiddenCharsTable::onChange()
153 if( mpModel )
155 mpModel->ReformatAllTextObjects();
159 SdUnoForbiddenCharsTable::~SdUnoForbiddenCharsTable()
161 SolarMutexGuard g;
163 if( mpModel )
164 EndListening( *mpModel );
167 void SdUnoForbiddenCharsTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) throw()
169 if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
170 return;
171 const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
172 if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
174 mpModel = nullptr;
178 const sal_uInt16 WID_MODEL_LANGUAGE = 1;
179 const sal_uInt16 WID_MODEL_TABSTOP = 2;
180 const sal_uInt16 WID_MODEL_VISAREA = 3;
181 const sal_uInt16 WID_MODEL_MAPUNIT = 4;
182 const sal_uInt16 WID_MODEL_FORBCHARS = 5;
183 const sal_uInt16 WID_MODEL_CONTFOCUS = 6;
184 const sal_uInt16 WID_MODEL_DSGNMODE = 7;
185 const sal_uInt16 WID_MODEL_BASICLIBS = 8;
186 const sal_uInt16 WID_MODEL_RUNTIMEUID = 9;
187 const sal_uInt16 WID_MODEL_BUILDID = 10;
188 const sal_uInt16 WID_MODEL_HASVALIDSIGNATURES = 11;
189 const sal_uInt16 WID_MODEL_DIALOGLIBS = 12;
190 const sal_uInt16 WID_MODEL_FONTS = 13;
191 const sal_uInt16 WID_MODEL_INTEROPGRABBAG = 14;
193 static const SvxItemPropertySet* ImplGetDrawModelPropertySet()
195 // Attention: the first parameter HAS TO BE sorted!!!
196 const static SfxItemPropertyMapEntry aDrawModelPropertyMap_Impl[] =
198 { OUString("BuildId"), WID_MODEL_BUILDID, ::cppu::UnoType<OUString>::get(), 0, 0},
199 { OUString(sUNO_Prop_CharLocale), WID_MODEL_LANGUAGE, ::cppu::UnoType<lang::Locale>::get(), 0, 0},
200 { OUString(sUNO_Prop_TabStop), WID_MODEL_TABSTOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0},
201 { OUString(sUNO_Prop_VisibleArea), WID_MODEL_VISAREA, ::cppu::UnoType<awt::Rectangle>::get(), 0, 0},
202 { OUString(sUNO_Prop_MapUnit), WID_MODEL_MAPUNIT, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0},
203 { OUString(sUNO_Prop_ForbiddenCharacters), WID_MODEL_FORBCHARS, cppu::UnoType<i18n::XForbiddenCharacters>::get(), beans::PropertyAttribute::READONLY, 0},
204 { OUString(sUNO_Prop_AutomContFocus), WID_MODEL_CONTFOCUS, cppu::UnoType<bool>::get(), 0, 0},
205 { OUString(sUNO_Prop_ApplyFrmDsgnMode), WID_MODEL_DSGNMODE, cppu::UnoType<bool>::get(), 0, 0},
206 { OUString("BasicLibraries"), WID_MODEL_BASICLIBS, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0},
207 { OUString("DialogLibraries"), WID_MODEL_DIALOGLIBS, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0},
208 { OUString(sUNO_Prop_RuntimeUID), WID_MODEL_RUNTIMEUID, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0},
209 { OUString(sUNO_Prop_HasValidSignatures), WID_MODEL_HASVALIDSIGNATURES, ::cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::READONLY, 0},
210 { OUString("Fonts"), WID_MODEL_FONTS, cppu::UnoType<uno::Sequence<uno::Any>>::get(), beans::PropertyAttribute::READONLY, 0},
211 { OUString(sUNO_Prop_InteropGrabBag), WID_MODEL_INTEROPGRABBAG, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(), 0, 0},
212 { OUString(), 0, css::uno::Type(), 0, 0 }
214 static SvxItemPropertySet aDrawModelPropertySet_Impl( aDrawModelPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
215 return &aDrawModelPropertySet_Impl;
218 // this ctor is used from the DocShell
219 SdXImpressDocument::SdXImpressDocument(::sd::DrawDocShell* pShell, bool bClipBoard)
220 : SfxBaseModel( pShell ),
221 mpDocShell( pShell ),
222 mpDoc( pShell ? pShell->GetDoc() : nullptr ),
223 mbDisposed(false),
224 mbImpressDoc( pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocumentType() == DocumentType::Impress ),
225 mbClipBoard( bClipBoard ),
226 mpPropSet( ImplGetDrawModelPropertySet() )
228 if( mpDoc )
230 StartListening( *mpDoc );
232 else
234 OSL_FAIL("DocShell is invalid");
238 SdXImpressDocument::SdXImpressDocument(SdDrawDocument* pDoc, bool bClipBoard)
239 : SfxBaseModel( nullptr ),
240 mpDocShell( nullptr ),
241 mpDoc( pDoc ),
242 mbDisposed(false),
243 mbImpressDoc( pDoc && pDoc->GetDocumentType() == DocumentType::Impress ),
244 mbClipBoard( bClipBoard ),
245 mpPropSet( ImplGetDrawModelPropertySet() )
247 if( mpDoc )
249 StartListening( *mpDoc );
251 else
253 OSL_FAIL("SdDrawDocument is invalid");
257 /***********************************************************************
259 ***********************************************************************/
260 SdXImpressDocument::~SdXImpressDocument() throw()
264 // XInterface
265 uno::Any SAL_CALL SdXImpressDocument::queryInterface( const uno::Type & rType )
267 uno::Any aAny;
269 if (rType == cppu::UnoType<lang::XServiceInfo>::get())
270 aAny <<= uno::Reference<lang::XServiceInfo>(this);
271 else if (rType == cppu::UnoType<beans::XPropertySet>::get())
272 aAny <<= uno::Reference<beans::XPropertySet>(this);
273 else if (rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
274 aAny <<= uno::Reference<lang::XMultiServiceFactory>(this);
275 else if (rType == cppu::UnoType<drawing::XDrawPageDuplicator>::get())
276 aAny <<= uno::Reference<drawing::XDrawPageDuplicator>(this);
277 else if (rType == cppu::UnoType<drawing::XLayerSupplier>::get())
278 aAny <<= uno::Reference<drawing::XLayerSupplier>(this);
279 else if (rType == cppu::UnoType<drawing::XMasterPagesSupplier>::get())
280 aAny <<= uno::Reference<drawing::XMasterPagesSupplier>(this);
281 else if (rType == cppu::UnoType<drawing::XDrawPagesSupplier>::get())
282 aAny <<= uno::Reference<drawing::XDrawPagesSupplier>(this);
283 else if (rType == cppu::UnoType<presentation::XHandoutMasterSupplier>::get())
284 aAny <<= uno::Reference<presentation::XHandoutMasterSupplier>(this);
285 else if (rType == cppu::UnoType<document::XLinkTargetSupplier>::get())
286 aAny <<= uno::Reference<document::XLinkTargetSupplier>(this);
287 else if (rType == cppu::UnoType<style::XStyleFamiliesSupplier>::get())
288 aAny <<= uno::Reference<style::XStyleFamiliesSupplier>(this);
289 else if (rType == cppu::UnoType<css::ucb::XAnyCompareFactory>::get())
290 aAny <<= uno::Reference<css::ucb::XAnyCompareFactory>(this);
291 else if (rType == cppu::UnoType<view::XRenderable>::get())
292 aAny <<= uno::Reference<view::XRenderable>(this);
293 else if (mbImpressDoc && rType == cppu::UnoType<presentation::XPresentationSupplier>::get())
294 aAny <<= uno::Reference< presentation::XPresentationSupplier >(this);
295 else if (mbImpressDoc && rType == cppu::UnoType<presentation::XCustomPresentationSupplier>::get())
296 aAny <<= uno::Reference< presentation::XCustomPresentationSupplier >(this);
297 else
298 return SfxBaseModel::queryInterface(rType);
300 return aAny;
303 void SAL_CALL SdXImpressDocument::acquire() throw ( )
305 SfxBaseModel::acquire();
308 void SAL_CALL SdXImpressDocument::release() throw ( )
310 if (osl_atomic_decrement( &m_refCount ) != 0)
311 return;
313 // restore reference count:
314 osl_atomic_increment( &m_refCount );
315 if(!mbDisposed)
319 dispose();
321 catch (const uno::RuntimeException&)
323 // don't break throw ()
324 TOOLS_WARN_EXCEPTION( "sd", "" );
327 SfxBaseModel::release();
330 namespace
332 class theSdXImpressDocumentUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSdXImpressDocumentUnoTunnelId> {};
335 // XUnoTunnel
336 const css::uno::Sequence< sal_Int8 > & SdXImpressDocument::getUnoTunnelId() throw()
338 return theSdXImpressDocumentUnoTunnelId::get().getSeq();
341 sal_Int64 SAL_CALL SdXImpressDocument::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier )
343 if( isUnoTunnelId<SdXImpressDocument>(rIdentifier) )
344 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
346 if( isUnoTunnelId<SdrModel>(rIdentifier) )
347 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(mpDoc));
349 return SfxBaseModel::getSomething( rIdentifier );
352 // XTypeProvider
353 uno::Sequence< uno::Type > SAL_CALL SdXImpressDocument::getTypes( )
355 ::SolarMutexGuard aGuard;
357 if( !maTypeSequence.hasElements() )
359 uno::Sequence< uno::Type > aTypes( SfxBaseModel::getTypes() );
360 aTypes = comphelper::concatSequences(aTypes,
361 uno::Sequence {
362 cppu::UnoType<beans::XPropertySet>::get(),
363 cppu::UnoType<lang::XServiceInfo>::get(),
364 cppu::UnoType<lang::XMultiServiceFactory>::get(),
365 cppu::UnoType<drawing::XDrawPageDuplicator>::get(),
366 cppu::UnoType<drawing::XLayerSupplier>::get(),
367 cppu::UnoType<drawing::XMasterPagesSupplier>::get(),
368 cppu::UnoType<drawing::XDrawPagesSupplier>::get(),
369 cppu::UnoType<document::XLinkTargetSupplier>::get(),
370 cppu::UnoType<style::XStyleFamiliesSupplier>::get(),
371 cppu::UnoType<css::ucb::XAnyCompareFactory>::get(),
372 cppu::UnoType<view::XRenderable>::get() });
373 if( mbImpressDoc )
375 aTypes = comphelper::concatSequences(aTypes,
376 uno::Sequence {
377 cppu::UnoType<presentation::XPresentationSupplier>::get(),
378 cppu::UnoType<presentation::XCustomPresentationSupplier>::get(),
379 cppu::UnoType<presentation::XHandoutMasterSupplier>::get() });
381 maTypeSequence = aTypes;
384 return maTypeSequence;
387 uno::Sequence< sal_Int8 > SAL_CALL SdXImpressDocument::getImplementationId( )
389 return css::uno::Sequence<sal_Int8>();
392 /***********************************************************************
394 ***********************************************************************/
395 void SdXImpressDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
397 if( mpDoc )
399 if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
401 const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
402 if( hasEventListeners() )
404 document::EventObject aEvent;
405 if( SvxUnoDrawMSFactory::createEvent( mpDoc, pSdrHint, aEvent ) )
406 notifyEvent( aEvent );
409 if( pSdrHint->GetKind() == SdrHintKind::ModelCleared )
411 if( mpDoc )
412 EndListening( *mpDoc );
413 mpDoc = nullptr;
414 mpDocShell = nullptr;
417 else
419 // did our SdDrawDocument just died?
420 if(rHint.GetId() == SfxHintId::Dying)
422 // yes, so we ask for a new one
423 if( mpDocShell )
425 SdDrawDocument *pNewDoc = mpDocShell->GetDoc();
427 // is there a new one?
428 if( pNewDoc != mpDoc )
430 mpDoc = pNewDoc;
431 if(mpDoc)
432 StartListening( *mpDoc );
438 SfxBaseModel::Notify( rBC, rHint );
441 /******************************************************************************
443 ******************************************************************************/
444 SdPage* SdXImpressDocument::InsertSdPage( sal_uInt16 nPage, bool bDuplicate )
446 sal_uInt16 nPageCount = mpDoc->GetSdPageCount( PageKind::Standard );
447 SdrLayerAdmin& rLayerAdmin = mpDoc->GetLayerAdmin();
448 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
449 SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
451 SdPage* pStandardPage = nullptr;
453 if( 0 == nPageCount )
455 // this is only used for clipboard where we only have one page
456 pStandardPage = mpDoc->AllocSdPage(false);
458 Size aDefSize(21000, 29700); // A4 portrait orientation
459 pStandardPage->SetSize( aDefSize );
460 mpDoc->InsertPage(pStandardPage, 0);
462 else
464 // here we determine the page after which we should insert
465 SdPage* pPreviousStandardPage = mpDoc->GetSdPage( std::min( static_cast<sal_uInt16>(nPageCount - 1), nPage ), PageKind::Standard );
466 SdrLayerIDSet aVisibleLayers = pPreviousStandardPage->TRG_GetMasterPageVisibleLayers();
467 bool bIsPageBack = aVisibleLayers.IsSet( aBckgrnd );
468 bool bIsPageObj = aVisibleLayers.IsSet( aBckgrndObj );
470 // AutoLayouts must be ready
471 mpDoc->StopWorkStartupDelay();
473 /* First we create a standard page and then a notes page. It is
474 guaranteed, that after a standard page the corresponding notes page
475 follows. */
477 sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
478 SdPage* pPreviousNotesPage = static_cast<SdPage*>( mpDoc->GetPage( nStandardPageNum - 1 ) );
479 sal_uInt16 nNotesPageNum = nStandardPageNum + 1;
481 /**************************************************************
482 * standard page
483 **************************************************************/
484 if( bDuplicate )
485 pStandardPage = static_cast<SdPage*>( pPreviousStandardPage->CloneSdrPage(*mpDoc) );
486 else
487 pStandardPage = mpDoc->AllocSdPage(false);
489 pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
490 pStandardPage->SetBorder( pPreviousStandardPage->GetLeftBorder(),
491 pPreviousStandardPage->GetUpperBorder(),
492 pPreviousStandardPage->GetRightBorder(),
493 pPreviousStandardPage->GetLowerBorder() );
494 pStandardPage->SetOrientation( pPreviousStandardPage->GetOrientation() );
495 pStandardPage->SetName(OUString());
497 // insert page after current page
498 mpDoc->InsertPage(pStandardPage, nStandardPageNum);
500 if( !bDuplicate )
502 // use MasterPage of the current page
503 pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
504 pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
505 pStandardPage->SetAutoLayout(AUTOLAYOUT_NONE, true );
508 aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
509 aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
510 aVisibleLayers.Set(aBckgrnd, bIsPageBack);
511 aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
512 pStandardPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
514 /**************************************************************
515 * notes page
516 **************************************************************/
517 SdPage* pNotesPage = nullptr;
519 if( bDuplicate )
520 pNotesPage = static_cast<SdPage*>( pPreviousNotesPage->CloneSdrPage(*mpDoc) );
521 else
522 pNotesPage = mpDoc->AllocSdPage(false);
524 pNotesPage->SetSize( pPreviousNotesPage->GetSize() );
525 pNotesPage->SetBorder( pPreviousNotesPage->GetLeftBorder(),
526 pPreviousNotesPage->GetUpperBorder(),
527 pPreviousNotesPage->GetRightBorder(),
528 pPreviousNotesPage->GetLowerBorder() );
529 pNotesPage->SetOrientation( pPreviousNotesPage->GetOrientation() );
530 pNotesPage->SetName(OUString());
531 pNotesPage->SetPageKind(PageKind::Notes);
533 // insert page after current page
534 mpDoc->InsertPage(pNotesPage, nNotesPageNum);
536 if( !bDuplicate )
538 // use MasterPage of the current page
539 pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
540 pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
541 pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true );
545 SetModified();
547 return pStandardPage;
550 void SdXImpressDocument::SetModified() throw()
552 if( mpDoc )
553 mpDoc->SetChanged();
556 // XModel
557 void SAL_CALL SdXImpressDocument::lockControllers( )
559 ::SolarMutexGuard aGuard;
561 if( nullptr == mpDoc )
562 throw lang::DisposedException();
564 mpDoc->setLock(true);
567 void SAL_CALL SdXImpressDocument::unlockControllers( )
569 ::SolarMutexGuard aGuard;
571 if( nullptr == mpDoc )
572 throw lang::DisposedException();
574 if( mpDoc->isLocked() )
576 mpDoc->setLock(false);
580 sal_Bool SAL_CALL SdXImpressDocument::hasControllersLocked( )
582 ::SolarMutexGuard aGuard;
584 if( nullptr == mpDoc )
585 throw lang::DisposedException();
587 return mpDoc->isLocked();
590 uno::Reference < container::XIndexAccess > SAL_CALL SdXImpressDocument::getViewData()
592 ::SolarMutexGuard aGuard;
594 if( nullptr == mpDoc )
595 throw lang::DisposedException();
597 uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
599 if( !xRet.is() )
601 const std::vector<std::unique_ptr<sd::FrameView>> &rList = mpDoc->GetFrameViewList();
603 if( !rList.empty() )
605 xRet = document::IndexedPropertyValues::create( ::comphelper::getProcessComponentContext() );
607 uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
608 DBG_ASSERT( xCont.is(), "SdXImpressDocument::getViewData() failed for OLE object" );
609 if( xCont.is() )
611 for( sal_uInt32 i = 0, n = rList.size(); i < n; i++ )
613 ::sd::FrameView* pFrameView = rList[ i ].get();
615 uno::Sequence< beans::PropertyValue > aSeq;
616 pFrameView->WriteUserDataSequence( aSeq );
617 xCont->insertByIndex( i, uno::makeAny( aSeq ) );
623 return xRet;
626 void SAL_CALL SdXImpressDocument::setViewData( const uno::Reference < container::XIndexAccess >& xData )
628 ::SolarMutexGuard aGuard;
630 if( nullptr == mpDoc )
631 throw lang::DisposedException();
633 SfxBaseModel::setViewData( xData );
634 if( !(mpDocShell && (mpDocShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) && xData.is()) )
635 return;
637 const sal_Int32 nCount = xData->getCount();
639 std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
641 rViews.clear();
643 uno::Sequence< beans::PropertyValue > aSeq;
644 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
646 if( xData->getByIndex( nIndex ) >>= aSeq )
648 std::unique_ptr<::sd::FrameView> pFrameView(new ::sd::FrameView( mpDoc ));
649 pFrameView->ReadUserDataSequence( aSeq );
650 rViews.push_back( std::move(pFrameView) );
655 // XDrawPageDuplicator
656 uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::duplicate( const uno::Reference< drawing::XDrawPage >& xPage )
658 ::SolarMutexGuard aGuard;
660 if( nullptr == mpDoc )
661 throw lang::DisposedException();
663 // get pPage from xPage and determine the Id (nPos ) afterwards
664 SvxDrawPage* pSvxPage = comphelper::getUnoTunnelImplementation<SvxDrawPage>( xPage );
665 if( pSvxPage )
667 SdPage* pPage = static_cast<SdPage*>( pSvxPage->GetSdrPage() );
668 sal_uInt16 nPos = pPage->GetPageNum();
669 nPos = ( nPos - 1 ) / 2;
670 pPage = InsertSdPage( nPos, true );
671 if( pPage )
673 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
674 return xDrawPage;
678 uno::Reference< drawing::XDrawPage > xDrawPage;
679 return xDrawPage;
682 // XDrawPagesSupplier
683 uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getDrawPages()
685 ::SolarMutexGuard aGuard;
687 if( nullptr == mpDoc )
688 throw lang::DisposedException();
690 uno::Reference< drawing::XDrawPages > xDrawPages( mxDrawPagesAccess );
692 if( !xDrawPages.is() )
694 initializeDocument();
695 mxDrawPagesAccess = xDrawPages = new SdDrawPagesAccess(*this);
698 return xDrawPages;
701 // XMasterPagesSupplier
702 uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getMasterPages()
704 ::SolarMutexGuard aGuard;
706 if( nullptr == mpDoc )
707 throw lang::DisposedException();
709 uno::Reference< drawing::XDrawPages > xMasterPages( mxMasterPagesAccess );
711 if( !xMasterPages.is() )
713 if ( !hasControllersLocked() )
714 initializeDocument();
715 mxMasterPagesAccess = xMasterPages = new SdMasterPagesAccess(*this);
718 return xMasterPages;
721 // XLayerManagerSupplier
722 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLayerManager( )
724 ::SolarMutexGuard aGuard;
726 if( nullptr == mpDoc )
727 throw lang::DisposedException();
729 uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager );
731 if( !xLayerManager.is() )
732 mxLayerManager = xLayerManager = new SdLayerManager(*this);
734 return xLayerManager;
737 // XCustomPresentationSupplier
738 uno::Reference< container::XNameContainer > SAL_CALL SdXImpressDocument::getCustomPresentations()
740 ::SolarMutexGuard aGuard;
742 if( nullptr == mpDoc )
743 throw lang::DisposedException();
745 uno::Reference< container::XNameContainer > xCustomPres( mxCustomPresentationAccess );
747 if( !xCustomPres.is() )
748 mxCustomPresentationAccess = xCustomPres = new SdXCustomPresentationAccess(*this);
750 return xCustomPres;
753 // XPresentationSupplier
754 uno::Reference< presentation::XPresentation > SAL_CALL SdXImpressDocument::getPresentation()
756 ::SolarMutexGuard aGuard;
758 if( nullptr == mpDoc )
759 throw lang::DisposedException();
761 return uno::Reference< presentation::XPresentation >( mpDoc->getPresentation().get() );
764 // XHandoutMasterSupplier
765 uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::getHandoutMasterPage()
767 ::SolarMutexGuard aGuard;
769 if( nullptr == mpDoc )
770 throw lang::DisposedException();
772 uno::Reference< drawing::XDrawPage > xPage;
774 initializeDocument();
775 SdPage* pPage = mpDoc->GetMasterSdPage(0, PageKind::Handout);
776 if (pPage)
777 xPage.set(pPage->getUnoPage(), uno::UNO_QUERY);
778 return xPage;
781 // XMultiServiceFactory ( SvxFmMSFactory )
783 css::uno::Reference<css::uno::XInterface> SdXImpressDocument::create(
784 OUString const & aServiceSpecifier, OUString const & referer)
786 ::SolarMutexGuard aGuard;
788 if( nullptr == mpDoc )
789 throw lang::DisposedException();
791 if( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
793 if( !mxDashTable.is() )
794 mxDashTable = SvxUnoDashTable_createInstance( mpDoc );
796 return mxDashTable;
798 if( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
800 if( !mxGradientTable.is() )
801 mxGradientTable = SvxUnoGradientTable_createInstance( mpDoc );
803 return mxGradientTable;
805 if( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
807 if( !mxHatchTable.is() )
808 mxHatchTable = SvxUnoHatchTable_createInstance( mpDoc );
810 return mxHatchTable;
812 if( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
814 if( !mxBitmapTable.is() )
815 mxBitmapTable = SvxUnoBitmapTable_createInstance( mpDoc );
817 return mxBitmapTable;
819 if( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
821 if( !mxTransGradientTable.is() )
822 mxTransGradientTable = SvxUnoTransGradientTable_createInstance( mpDoc );
824 return mxTransGradientTable;
826 if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
828 if( !mxMarkerTable.is() )
829 mxMarkerTable = SvxUnoMarkerTable_createInstance( mpDoc );
831 return mxMarkerTable;
833 if( aServiceSpecifier == "com.sun.star.text.NumberingRules" )
835 return uno::Reference< uno::XInterface >( SvxCreateNumRule( mpDoc ), uno::UNO_QUERY );
837 if( aServiceSpecifier == "com.sun.star.drawing.Background" )
839 return uno::Reference< uno::XInterface >(
840 static_cast<uno::XWeak*>(new SdUnoPageBackground( mpDoc )));
843 if( aServiceSpecifier == "com.sun.star.drawing.Defaults" )
845 if( !mxDrawingPool.is() )
846 mxDrawingPool = SdUnoCreatePool( mpDoc );
848 return mxDrawingPool;
852 if ( aServiceSpecifier == sUNO_Service_ImageMapRectangleObject )
854 return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
857 if ( aServiceSpecifier == sUNO_Service_ImageMapCircleObject )
859 return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
862 if ( aServiceSpecifier == sUNO_Service_ImageMapPolygonObject )
864 return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
867 if( aServiceSpecifier == "com.sun.star.document.Settings" ||
868 ( !mbImpressDoc && ( aServiceSpecifier == "com.sun.star.drawing.DocumentSettings" ) ) ||
869 ( mbImpressDoc && ( aServiceSpecifier == "com.sun.star.presentation.DocumentSettings" ) ) )
871 return sd::DocumentSettings_createInstance( this );
874 if( aServiceSpecifier == "com.sun.star.text.TextField.DateTime" ||
875 aServiceSpecifier == "com.sun.star.text.textfield.DateTime" )
877 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::DATE ));
880 if( aServiceSpecifier == "com.sun.star.presentation.TextField.Header" ||
881 aServiceSpecifier == "com.sun.star.presentation.textfield.Header" )
883 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_HEADER ));
886 if( aServiceSpecifier == "com.sun.star.presentation.TextField.Footer" ||
887 aServiceSpecifier == "com.sun.star.presentation.textfield.Footer" )
889 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_FOOTER ));
892 if( aServiceSpecifier == "com.sun.star.presentation.TextField.DateTime" ||
893 aServiceSpecifier == "com.sun.star.presentation.textfield.DateTime" )
895 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_DATE_TIME ));
898 if( aServiceSpecifier == "com.sun.star.text.TextField.PageName" ||
899 aServiceSpecifier == "com.sun.star.text.textfield.PageName" )
901 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PAGE_NAME ));
904 if (aServiceSpecifier == "com.sun.star.text.TextField.DocInfo.Custom" ||
905 aServiceSpecifier == "com.sun.star.text.textfield.DocInfo.Custom")
907 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField(text::textfield::Type::DOCINFO_CUSTOM));
910 if( aServiceSpecifier == "com.sun.star.xml.NamespaceMap" )
912 static sal_uInt16 aWhichIds[] = { SDRATTR_XMLATTRIBUTES, EE_CHAR_XMLATTRIBS, EE_PARA_XMLATTRIBS, 0 };
914 return svx::NamespaceMap_createInstance( aWhichIds, &mpDoc->GetItemPool() );
917 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
918 if (aServiceSpecifier == "com.sun.star.document.ExportGraphicStorageHandler")
920 return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Write ));
923 if (aServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler")
925 return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Read ));
928 if( aServiceSpecifier == "com.sun.star.document.ExportEmbeddedObjectResolver" )
930 comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
931 if( nullptr == pPersist )
932 throw lang::DisposedException();
934 return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Write ));
937 if( aServiceSpecifier == "com.sun.star.document.ImportEmbeddedObjectResolver" )
939 comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
940 if( nullptr == pPersist )
941 throw lang::DisposedException();
943 return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Read ));
946 uno::Reference< uno::XInterface > xRet;
948 if( aServiceSpecifier.startsWith( "com.sun.star.presentation.") )
950 const OUString aType( aServiceSpecifier.copy(26) );
951 SvxShape* pShape = nullptr;
953 sal_uInt16 nType = OBJ_TEXT;
954 // create a shape wrapper
955 if( aType.startsWith( "TitleTextShape" ) )
957 nType = OBJ_TEXT;
959 else if( aType.startsWith( "OutlinerShape" ) )
961 nType = OBJ_TEXT;
963 else if( aType.startsWith( "SubtitleShape" ) )
965 nType = OBJ_TEXT;
967 else if( aType.startsWith( "GraphicObjectShape" ) )
969 nType = OBJ_GRAF;
971 else if( aType.startsWith( "PageShape" ) )
973 nType = OBJ_PAGE;
975 else if( aType.startsWith( "OLE2Shape" ) )
977 nType = OBJ_OLE2;
979 else if( aType.startsWith( "ChartShape" ) )
981 nType = OBJ_OLE2;
983 else if( aType.startsWith( "CalcShape" ) )
985 nType = OBJ_OLE2;
987 else if( aType.startsWith( "TableShape" ) )
989 nType = OBJ_TABLE;
991 else if( aType.startsWith( "OrgChartShape" ) )
993 nType = OBJ_OLE2;
995 else if( aType.startsWith( "NotesShape" ) )
997 nType = OBJ_TEXT;
999 else if( aType.startsWith( "HandoutShape" ) )
1001 nType = OBJ_PAGE;
1003 else if( aType.startsWith( "FooterShape" ) )
1005 nType = OBJ_TEXT;
1007 else if( aType.startsWith( "HeaderShape" ) )
1009 nType = OBJ_TEXT;
1011 else if( aType.startsWith( "SlideNumberShape" ) )
1013 nType = OBJ_TEXT;
1015 else if( aType.startsWith( "DateTimeShape" ) )
1017 nType = OBJ_TEXT;
1019 else if( aType.startsWith( "MediaShape" ) )
1021 nType = OBJ_MEDIA;
1023 else
1025 throw lang::ServiceNotRegisteredException();
1028 // create the API wrapper
1029 pShape = CreateSvxShapeByTypeAndInventor( nType, SdrInventor::Default, referer );
1031 // set shape type
1032 if( pShape && !mbClipBoard )
1033 pShape->SetShapeType(aServiceSpecifier);
1035 xRet = static_cast<uno::XWeak*>(pShape);
1037 else if ( aServiceSpecifier == "com.sun.star.drawing.TableShape" )
1039 SvxShape* pShape = CreateSvxShapeByTypeAndInventor( OBJ_TABLE, SdrInventor::Default, referer );
1040 if( pShape && !mbClipBoard )
1041 pShape->SetShapeType(aServiceSpecifier);
1043 xRet = static_cast<uno::XWeak*>(pShape);
1045 else
1047 xRet = SvxFmMSFactory::createInstance( aServiceSpecifier );
1050 uno::Reference< drawing::XShape > xShape( xRet, uno::UNO_QUERY );
1051 SvxShape* pShape = xShape.is() ? comphelper::getUnoTunnelImplementation<SvxShape>(xShape) : nullptr;
1052 if (pShape)
1054 xRet.clear();
1055 new SdXShape( pShape, this );
1056 xRet = xShape;
1057 xShape.clear();
1060 return xRet;
1063 uno::Reference< uno::XInterface > SAL_CALL SdXImpressDocument::createInstance( const OUString& aServiceSpecifier )
1065 return create(aServiceSpecifier, "");
1068 css::uno::Reference<css::uno::XInterface>
1069 SdXImpressDocument::createInstanceWithArguments(
1070 OUString const & ServiceSpecifier,
1071 css::uno::Sequence<css::uno::Any> const & Arguments)
1073 OUString arg;
1074 if ((ServiceSpecifier == "com.sun.star.drawing.GraphicObjectShape"
1075 || ServiceSpecifier == "com.sun.star.drawing.MediaShape"
1076 || ServiceSpecifier == "com.sun.star.presentation.MediaShape")
1077 && Arguments.getLength() == 1 && (Arguments[0] >>= arg))
1079 return create(ServiceSpecifier, arg);
1081 return SvxFmMSFactory::createInstanceWithArguments(
1082 ServiceSpecifier, Arguments);
1085 uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getAvailableServiceNames()
1087 ::SolarMutexGuard aGuard;
1089 if( nullptr == mpDoc )
1090 throw lang::DisposedException();
1092 const uno::Sequence< OUString > aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
1094 uno::Sequence< OUString > aSNS( mbImpressDoc ? 36 : 19 );
1096 sal_uInt16 i(0);
1098 aSNS[i++] = "com.sun.star.drawing.DashTable";
1099 aSNS[i++] = "com.sun.star.drawing.GradientTable";
1100 aSNS[i++] = "com.sun.star.drawing.HatchTable";
1101 aSNS[i++] = "com.sun.star.drawing.BitmapTable";
1102 aSNS[i++] = "com.sun.star.drawing.TransparencyGradientTable";
1103 aSNS[i++] = "com.sun.star.drawing.MarkerTable";
1104 aSNS[i++] = "com.sun.star.text.NumberingRules";
1105 aSNS[i++] = "com.sun.star.drawing.Background";
1106 aSNS[i++] = "com.sun.star.document.Settings";
1107 aSNS[i++] = sUNO_Service_ImageMapRectangleObject;
1108 aSNS[i++] = sUNO_Service_ImageMapCircleObject;
1109 aSNS[i++] = sUNO_Service_ImageMapPolygonObject;
1110 aSNS[i++] = "com.sun.star.xml.NamespaceMap";
1112 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
1113 aSNS[i++] = "com.sun.star.document.ExportGraphicStorageHandler";
1114 aSNS[i++] = "com.sun.star.document.ImportGraphicStorageHandler";
1115 aSNS[i++] = "com.sun.star.document.ExportEmbeddedObjectResolver";
1116 aSNS[i++] = "com.sun.star.document.ImportEmbeddedObjectResolver";
1117 aSNS[i++] = "com.sun.star.drawing.TableShape";
1119 if(mbImpressDoc)
1121 aSNS[i++] = "com.sun.star.presentation.TitleTextShape";
1122 aSNS[i++] = "com.sun.star.presentation.OutlinerShape";
1123 aSNS[i++] = "com.sun.star.presentation.SubtitleShape";
1124 aSNS[i++] = "com.sun.star.presentation.GraphicObjectShape";
1125 aSNS[i++] = "com.sun.star.presentation.ChartShape";
1126 aSNS[i++] = "com.sun.star.presentation.PageShape";
1127 aSNS[i++] = "com.sun.star.presentation.OLE2Shape";
1128 aSNS[i++] = "com.sun.star.presentation.TableShape";
1129 aSNS[i++] = "com.sun.star.presentation.OrgChartShape";
1130 aSNS[i++] = "com.sun.star.presentation.NotesShape";
1131 aSNS[i++] = "com.sun.star.presentation.HandoutShape";
1132 aSNS[i++] = "com.sun.star.presentation.DocumentSettings";
1133 aSNS[i++] = "com.sun.star.presentation.FooterShape";
1134 aSNS[i++] = "com.sun.star.presentation.HeaderShape";
1135 aSNS[i++] = "com.sun.star.presentation.SlideNumberShape";
1136 aSNS[i++] = "com.sun.star.presentation.DateTimeShape";
1137 aSNS[i++] = "com.sun.star.presentation.CalcShape";
1138 aSNS[i++] = "com.sun.star.presentation.MediaShape";
1140 else
1142 aSNS[i++] = "com.sun.star.drawing.DocumentSettings";
1145 DBG_ASSERT( i == aSNS.getLength(), "Sequence overrun!" );
1147 return comphelper::concatSequences( aSNS_ORG, aSNS );
1150 // lang::XServiceInfo
1151 OUString SAL_CALL SdXImpressDocument::getImplementationName()
1153 return "SdXImpressDocument";
1154 /* // Matching the .component information:
1155 return mbImpressDoc
1156 ? OUString("com.sun.star.comp.Draw.PresentationDocument")
1157 : OUString("com.sun.star.comp.Draw.DrawingDocument");
1161 sal_Bool SAL_CALL SdXImpressDocument::supportsService( const OUString& ServiceName )
1163 return cppu::supportsService(this, ServiceName);
1166 uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getSupportedServiceNames()
1168 ::SolarMutexGuard aGuard;
1170 return { "com.sun.star.document.OfficeDocument",
1171 "com.sun.star.drawing.GenericDrawingDocument",
1172 "com.sun.star.drawing.DrawingDocumentFactory",
1173 mbImpressDoc?OUString("com.sun.star.presentation.PresentationDocument"):OUString("com.sun.star.drawing.DrawingDocument") };
1176 // XPropertySet
1177 uno::Reference< beans::XPropertySetInfo > SAL_CALL SdXImpressDocument::getPropertySetInfo( )
1179 ::SolarMutexGuard aGuard;
1180 return mpPropSet->getPropertySetInfo();
1183 void SAL_CALL SdXImpressDocument::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
1185 ::SolarMutexGuard aGuard;
1187 if( nullptr == mpDoc )
1188 throw lang::DisposedException();
1190 const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
1192 switch( pEntry ? pEntry->nWID : -1 )
1194 case WID_MODEL_LANGUAGE:
1196 lang::Locale aLocale;
1197 if(!(aValue >>= aLocale))
1198 throw lang::IllegalArgumentException();
1200 mpDoc->SetLanguage( LanguageTag::convertToLanguageType(aLocale), EE_CHAR_LANGUAGE );
1201 break;
1203 case WID_MODEL_TABSTOP:
1205 sal_Int32 nValue = 0;
1206 if(!(aValue >>= nValue) || nValue < 0 )
1207 throw lang::IllegalArgumentException();
1209 mpDoc->SetDefaultTabulator(static_cast<sal_uInt16>(nValue));
1210 break;
1212 case WID_MODEL_VISAREA:
1214 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1215 if( !pEmbeddedObj )
1216 break;
1218 awt::Rectangle aVisArea;
1219 if( !(aValue >>= aVisArea) || (aVisArea.Width < 0) || (aVisArea.Height < 0) )
1220 throw lang::IllegalArgumentException();
1222 sal_Int32 nRight, nTop;
1223 if (o3tl::checked_add(aVisArea.X, aVisArea.Width, nRight) || o3tl::checked_add(aVisArea.Y, aVisArea.Height, nTop))
1224 throw lang::IllegalArgumentException();
1226 pEmbeddedObj->SetVisArea(::tools::Rectangle(aVisArea.X, aVisArea.Y, nRight, nTop));
1228 break;
1229 case WID_MODEL_CONTFOCUS:
1231 bool bFocus = false;
1232 if( !(aValue >>= bFocus ) )
1233 throw lang::IllegalArgumentException();
1234 mpDoc->SetAutoControlFocus( bFocus );
1236 break;
1237 case WID_MODEL_DSGNMODE:
1239 bool bMode = false;
1240 if( !(aValue >>= bMode ) )
1241 throw lang::IllegalArgumentException();
1242 mpDoc->SetOpenInDesignMode( bMode );
1244 break;
1245 case WID_MODEL_BUILDID:
1246 aValue >>= maBuildId;
1247 return;
1248 case WID_MODEL_MAPUNIT:
1249 case WID_MODEL_BASICLIBS:
1250 case WID_MODEL_RUNTIMEUID: // is read-only
1251 case WID_MODEL_DIALOGLIBS:
1252 case WID_MODEL_FONTS:
1253 throw beans::PropertyVetoException();
1254 case WID_MODEL_INTEROPGRABBAG:
1255 setGrabBagItem(aValue);
1256 break;
1257 default:
1258 throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
1261 SetModified();
1264 uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& PropertyName )
1266 ::SolarMutexGuard aGuard;
1268 uno::Any aAny;
1269 if( nullptr == mpDoc )
1270 throw lang::DisposedException();
1272 const SfxItemPropertySimpleEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
1274 switch( pEntry ? pEntry->nWID : -1 )
1276 case WID_MODEL_LANGUAGE:
1278 LanguageType eLang = mpDoc->GetLanguage( EE_CHAR_LANGUAGE );
1279 aAny <<= LanguageTag::convertToLocale( eLang);
1280 break;
1282 case WID_MODEL_TABSTOP:
1283 aAny <<= static_cast<sal_Int32>(mpDoc->GetDefaultTabulator());
1284 break;
1285 case WID_MODEL_VISAREA:
1287 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1288 if( !pEmbeddedObj )
1289 break;
1291 const ::tools::Rectangle& aRect = pEmbeddedObj->GetVisArea();
1292 awt::Rectangle aVisArea( aRect.Left(), aRect.Top(), aRect.getWidth(), aRect.getHeight() );
1293 aAny <<= aVisArea;
1295 break;
1296 case WID_MODEL_MAPUNIT:
1298 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1299 if( !pEmbeddedObj )
1300 break;
1302 sal_Int16 nMeasureUnit = 0;
1303 SvxMapUnitToMeasureUnit( pEmbeddedObj->GetMapUnit(), nMeasureUnit );
1304 aAny <<= nMeasureUnit;
1306 break;
1307 case WID_MODEL_FORBCHARS:
1309 aAny <<= getForbiddenCharsTable();
1311 break;
1312 case WID_MODEL_CONTFOCUS:
1313 aAny <<= mpDoc->GetAutoControlFocus();
1314 break;
1315 case WID_MODEL_DSGNMODE:
1316 aAny <<= mpDoc->GetOpenInDesignMode();
1317 break;
1318 case WID_MODEL_BASICLIBS:
1319 aAny <<= mpDocShell->GetBasicContainer();
1320 break;
1321 case WID_MODEL_DIALOGLIBS:
1322 aAny <<= mpDocShell->GetDialogContainer();
1323 break;
1324 case WID_MODEL_RUNTIMEUID:
1325 aAny <<= getRuntimeUID();
1326 break;
1327 case WID_MODEL_BUILDID:
1328 return uno::Any( maBuildId );
1329 case WID_MODEL_HASVALIDSIGNATURES:
1330 aAny <<= hasValidSignatures();
1331 break;
1332 case WID_MODEL_FONTS:
1334 uno::Sequence<uno::Any> aSeq;
1335 int nSeqIndex = 0;
1337 sal_uInt16 const aWhichIds[] { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
1338 EE_CHAR_FONTINFO_CTL };
1340 const SfxItemPool& rPool = mpDoc->GetPool();
1342 for(sal_uInt16 nWhichId : aWhichIds)
1344 sal_uInt32 nItems = rPool.GetItemCount2( nWhichId );
1346 aSeq.realloc( aSeq.getLength() + nItems*5 + 5 );
1348 for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId))
1350 const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem);
1352 aSeq[nSeqIndex++] <<= pFont->GetFamilyName();
1353 aSeq[nSeqIndex++] <<= pFont->GetStyleName();
1354 aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily());
1355 aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch());
1356 aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet());
1359 const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetDefaultItem( nWhichId ));
1361 aSeq[nSeqIndex++] <<= rFont.GetFamilyName();
1362 aSeq[nSeqIndex++] <<= rFont.GetStyleName();
1363 aSeq[nSeqIndex++] <<= sal_Int16(rFont.GetFamily());
1364 aSeq[nSeqIndex++] <<= sal_Int16(rFont.GetPitch());
1365 aSeq[nSeqIndex++] <<= sal_Int16(rFont.GetCharSet());
1369 aSeq.realloc( nSeqIndex );
1370 aAny <<= aSeq;
1371 break;
1373 case WID_MODEL_INTEROPGRABBAG:
1374 getGrabBagItem(aAny);
1375 break;
1376 default:
1377 throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1380 return aAny;
1383 void SAL_CALL SdXImpressDocument::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {}
1384 void SAL_CALL SdXImpressDocument::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {}
1385 void SAL_CALL SdXImpressDocument::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {}
1386 void SAL_CALL SdXImpressDocument::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {}
1388 // XLinkTargetSupplier
1389 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLinks()
1391 ::SolarMutexGuard aGuard;
1393 if( nullptr == mpDoc )
1394 throw lang::DisposedException();
1396 uno::Reference< container::XNameAccess > xLinks( mxLinks );
1397 if( !xLinks.is() )
1398 mxLinks = xLinks = new SdDocLinkTargets( *this );
1399 return xLinks;
1402 // XStyleFamiliesSupplier
1403 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getStyleFamilies( )
1405 ::SolarMutexGuard aGuard;
1407 if( nullptr == mpDoc )
1408 throw lang::DisposedException();
1410 uno::Reference< container::XNameAccess > xStyles( dynamic_cast< container::XNameAccess* >( mpDoc->GetStyleSheetPool()) );
1411 return xStyles;
1414 // XAnyCompareFactory
1415 uno::Reference< css::ucb::XAnyCompare > SAL_CALL SdXImpressDocument::createAnyCompareByName( const OUString& )
1417 return SvxCreateNumRuleCompare();
1420 // XRenderable
1421 sal_Int32 SAL_CALL SdXImpressDocument::getRendererCount( const uno::Any& rSelection,
1422 const uno::Sequence< beans::PropertyValue >& )
1424 ::SolarMutexGuard aGuard;
1425 sal_Int32 nRet = 0;
1427 if( nullptr == mpDoc )
1428 throw lang::DisposedException();
1430 if (mpDocShell)
1432 uno::Reference< frame::XModel > xModel;
1434 rSelection >>= xModel;
1436 if( xModel == mpDocShell->GetModel() )
1437 nRet = mpDoc->GetSdPageCount( PageKind::Standard );
1438 else
1440 uno::Reference< drawing::XShapes > xShapes;
1442 rSelection >>= xShapes;
1444 if( xShapes.is() && xShapes->getCount() )
1445 nRet = 1;
1448 return nRet;
1451 uno::Sequence< beans::PropertyValue > SAL_CALL SdXImpressDocument::getRenderer( sal_Int32 , const uno::Any& ,
1452 const uno::Sequence< beans::PropertyValue >& rxOptions )
1454 ::SolarMutexGuard aGuard;
1456 if( nullptr == mpDoc )
1457 throw lang::DisposedException();
1459 bool bExportNotesPages = false;
1460 for( const auto& rOption : rxOptions )
1462 if ( rOption.Name == "ExportNotesPages" )
1463 rOption.Value >>= bExportNotesPages;
1465 uno::Sequence< beans::PropertyValue > aRenderer;
1466 if (mpDocShell)
1468 awt::Size aPageSize;
1469 if ( bExportNotesPages )
1471 Size aNotesPageSize = mpDoc->GetSdPage( 0, PageKind::Notes )->GetSize();
1472 aPageSize = awt::Size( aNotesPageSize.Width(), aNotesPageSize.Height() );
1474 else
1476 const ::tools::Rectangle aVisArea( mpDocShell->GetVisArea( embed::Aspects::MSOLE_DOCPRINT ) );
1477 aPageSize = awt::Size( aVisArea.GetWidth(), aVisArea.GetHeight() );
1479 aRenderer.realloc( 1 );
1481 aRenderer[ 0 ].Name = "PageSize" ;
1482 aRenderer[ 0 ].Value <<= aPageSize;
1484 return aRenderer;
1487 class ImplRenderPaintProc : public sdr::contact::ViewObjectContactRedirector
1489 const SdrLayerAdmin& rLayerAdmin;
1490 SdrPageView* const pSdrPageView;
1491 vcl::PDFExtOutDevData* const pPDFExtOutDevData;
1493 vcl::PDFWriter::StructElement ImplBegStructureTag( SdrObject& rObject );
1495 public:
1496 bool IsVisible ( const SdrObject* pObj ) const;
1497 bool IsPrintable( const SdrObject* pObj ) const;
1499 ImplRenderPaintProc( const SdrLayerAdmin& rLA, SdrPageView* pView, vcl::PDFExtOutDevData* pData );
1501 // all default implementations just call the same methods at the original. To do something
1502 // different, override the method and at least do what the method does.
1503 virtual drawinglayer::primitive2d::Primitive2DContainer createRedirectedPrimitive2DSequence(
1504 const sdr::contact::ViewObjectContact& rOriginal,
1505 const sdr::contact::DisplayInfo& rDisplayInfo) override;
1508 ImplRenderPaintProc::ImplRenderPaintProc( const SdrLayerAdmin& rLA, SdrPageView* pView, vcl::PDFExtOutDevData* pData )
1509 : ViewObjectContactRedirector(),
1510 rLayerAdmin ( rLA ),
1511 pSdrPageView ( pView ),
1512 pPDFExtOutDevData ( pData )
1516 static sal_Int32 ImplPDFGetBookmarkPage( const OUString& rBookmark, SdDrawDocument const & rDoc )
1518 sal_Int32 nPage = -1;
1520 OUString aBookmark( rBookmark );
1522 if( rBookmark.startsWith("#") )
1523 aBookmark = rBookmark.copy( 1 );
1525 // is the bookmark a page ?
1526 bool bIsMasterPage;
1527 sal_uInt16 nPgNum = rDoc.GetPageByName( aBookmark, bIsMasterPage );
1528 SdrObject* pObj = nullptr;
1530 if ( nPgNum == SDRPAGE_NOTFOUND )
1532 // is the bookmark an object ?
1533 pObj = rDoc.GetObj( aBookmark );
1534 if (pObj)
1535 nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum();
1537 if ( nPgNum != SDRPAGE_NOTFOUND )
1538 nPage = ( nPgNum - 1 ) / 2;
1539 return nPage;
1542 static void ImplPDFExportComments( const uno::Reference< drawing::XDrawPage >& xPage, vcl::PDFExtOutDevData& rPDFExtOutDevData )
1546 uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW );
1547 uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
1549 LanguageType eLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
1550 while( xAnnotationEnumeration->hasMoreElements() )
1552 uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() );
1554 geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() );
1555 uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
1556 util::DateTime aDateTime( xAnnotation->getDateTime() );
1558 Date aDate( aDateTime.Day, aDateTime.Month, aDateTime.Year );
1559 ::tools::Time aTime( ::tools::Time::EMPTY );
1560 OUString aStr = SvxDateTimeField::GetFormatted( aDate, aTime,
1561 SvxDateFormat::B, SvxTimeFormat::AppDefault,
1562 *(SD_MOD()->GetNumberFormatter()), eLanguage );
1564 vcl::PDFNote aNote;
1565 aNote.Title = xAnnotation->getAuthor() + ", " + aStr;
1566 aNote.Contents = xText->getString();
1567 rPDFExtOutDevData.CreateNote( ::tools::Rectangle( Point( static_cast< long >( aRealPoint2D.X * 100 ),
1568 static_cast< long >( aRealPoint2D.Y * 100 ) ), Size( 1000, 1000 ) ), aNote );
1571 catch (const uno::Exception&)
1576 static void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xShape, SdDrawDocument& rDoc, vcl::PDFExtOutDevData& rPDFExtOutDevData )
1578 if ( xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1580 uno::Reference< container::XIndexAccess > xIndexAccess( xShape, uno::UNO_QUERY );
1581 if ( xIndexAccess.is() )
1583 sal_Int32 i, nCount = xIndexAccess->getCount();
1584 for ( i = 0; i < nCount; i++ )
1586 uno::Reference< drawing::XShape > xSubShape( xIndexAccess->getByIndex( i ), uno::UNO_QUERY );
1587 if ( xSubShape.is() )
1588 ImplPDFExportShapeInteraction( xSubShape, rDoc, rPDFExtOutDevData );
1592 else
1594 uno::Reference< beans::XPropertySet > xShapePropSet( xShape, uno::UNO_QUERY );
1595 if( xShapePropSet.is() )
1597 Size aPageSize( rDoc.GetSdPage( 0, PageKind::Standard )->GetSize() );
1598 Point aPoint( 0, 0 );
1599 ::tools::Rectangle aPageRect( aPoint, aPageSize );
1601 awt::Point aShapePos( xShape->getPosition() );
1602 awt::Size aShapeSize( xShape->getSize() );
1603 ::tools::Rectangle aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) );
1605 // Handle linked videos.
1606 if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape")
1608 OUString aMediaURL;
1609 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
1610 if (!aMediaURL.isEmpty())
1612 sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, rPDFExtOutDevData.GetCurrentPageNumber());
1613 if (aMediaURL.startsWith("vnd.sun.star.Package:"))
1615 OUString aTempFileURL;
1616 xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
1617 rPDFExtOutDevData.SetScreenStream(nScreenId, aTempFileURL);
1619 else
1620 rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
1624 presentation::ClickAction eCa;
1625 uno::Any aAny( xShapePropSet->getPropertyValue( "OnClick" ) );
1626 if ( aAny >>= eCa )
1628 switch ( eCa )
1630 case presentation::ClickAction_LASTPAGE :
1632 sal_Int32 nCount = rDoc.GetSdPageCount( PageKind::Standard );
1633 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nCount - 1, vcl::PDFWriter::DestAreaType::FitRectangle );
1634 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1635 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1637 break;
1638 case presentation::ClickAction_FIRSTPAGE :
1640 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, 0, vcl::PDFWriter::DestAreaType::FitRectangle );
1641 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1642 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1644 break;
1645 case presentation::ClickAction_PREVPAGE :
1647 sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber();
1648 if ( nDestPage )
1649 nDestPage--;
1650 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1651 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1652 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1654 break;
1655 case presentation::ClickAction_NEXTPAGE :
1657 sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber() + 1;
1658 sal_Int32 nLastPage = rDoc.GetSdPageCount( PageKind::Standard ) - 1;
1659 if ( nDestPage > nLastPage )
1660 nDestPage = nLastPage;
1661 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1662 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1663 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1665 break;
1667 case presentation::ClickAction_PROGRAM :
1668 case presentation::ClickAction_BOOKMARK :
1669 case presentation::ClickAction_DOCUMENT :
1671 OUString aBookmark;
1672 xShapePropSet->getPropertyValue( "Bookmark" ) >>= aBookmark;
1673 if( !aBookmark.isEmpty() )
1675 switch( eCa )
1677 case presentation::ClickAction_DOCUMENT :
1678 case presentation::ClickAction_PROGRAM :
1680 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1681 rPDFExtOutDevData.SetLinkURL( nLinkId, aBookmark );
1683 break;
1684 case presentation::ClickAction_BOOKMARK :
1686 sal_Int32 nPage = ImplPDFGetBookmarkPage( aBookmark, rDoc );
1687 if ( nPage != -1 )
1689 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1690 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1691 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1694 break;
1695 default:
1696 break;
1700 break;
1702 case presentation::ClickAction_STOPPRESENTATION :
1703 case presentation::ClickAction_SOUND :
1704 case presentation::ClickAction_INVISIBLE :
1705 case presentation::ClickAction_VERB :
1706 case presentation::ClickAction_VANISH :
1707 case presentation::ClickAction_MACRO :
1708 default :
1709 break;
1716 vcl::PDFWriter::StructElement ImplRenderPaintProc::ImplBegStructureTag( SdrObject& rObject )
1718 vcl::PDFWriter::StructElement eElement(vcl::PDFWriter::NonStructElement);
1720 if ( pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportTaggedPDF() )
1722 SdrInventor nInventor = rObject.GetObjInventor();
1723 sal_uInt16 nIdentifier = rObject.GetObjIdentifier();
1724 bool bIsTextObj = dynamic_cast< const SdrTextObj *>( &rObject ) != nullptr;
1726 if ( nInventor == SdrInventor::Default )
1728 if ( nIdentifier == OBJ_GRUP )
1729 eElement = vcl::PDFWriter::Section;
1730 else if ( nIdentifier == OBJ_TITLETEXT )
1731 eElement = vcl::PDFWriter::Heading;
1732 else if ( nIdentifier == OBJ_OUTLINETEXT )
1733 eElement = vcl::PDFWriter::Division;
1734 else if ( !bIsTextObj || !static_cast<SdrTextObj&>(rObject).HasText() )
1735 eElement = vcl::PDFWriter::Figure;
1739 return eElement;
1742 drawinglayer::primitive2d::Primitive2DContainer ImplRenderPaintProc::createRedirectedPrimitive2DSequence(
1743 const sdr::contact::ViewObjectContact& rOriginal,
1744 const sdr::contact::DisplayInfo& rDisplayInfo)
1746 SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
1748 if(pObject)
1750 drawinglayer::primitive2d::Primitive2DContainer xRetval;
1752 if(pObject->getSdrPageFromSdrObject())
1754 if(pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, false))
1756 if(IsVisible(pObject) && IsPrintable(pObject))
1758 const vcl::PDFWriter::StructElement eElement(ImplBegStructureTag( *pObject ));
1759 const bool bTagUsed(vcl::PDFWriter::NonStructElement != eElement);
1761 xRetval = sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
1763 if(!xRetval.empty() && bTagUsed)
1765 // embed Primitive2DSequence in a structure tag element for
1766 // exactly this purpose (StructureTagPrimitive2D)
1768 const SdrPage* pSdrPage(pObject->getSdrPageFromSdrObject());
1769 const bool bBackground(nullptr != pSdrPage && pSdrPage->IsMasterPage());
1770 const bool bImage(pObject->GetObjIdentifier() == OBJ_GRAF);
1772 const drawinglayer::primitive2d::Primitive2DReference xReference(
1773 new drawinglayer::primitive2d::StructureTagPrimitive2D(
1774 eElement,
1775 bBackground,
1776 bImage,
1777 xRetval));
1779 xRetval = drawinglayer::primitive2d::Primitive2DContainer { xReference };
1785 return xRetval;
1787 else
1789 // not an object, maybe a page
1790 return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
1794 bool ImplRenderPaintProc::IsVisible( const SdrObject* pObj ) const
1796 bool bVisible = true;
1797 SdrLayerID nLayerId = pObj->GetLayer();
1798 if( pSdrPageView )
1800 const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
1801 if ( pSdrLayer )
1803 const OUString& aLayerName = pSdrLayer->GetName();
1804 bVisible = pSdrPageView->IsLayerVisible( aLayerName );
1807 return bVisible;
1809 bool ImplRenderPaintProc::IsPrintable( const SdrObject* pObj ) const
1811 bool bPrintable = true;
1812 SdrLayerID nLayerId = pObj->GetLayer();
1813 if( pSdrPageView )
1815 const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
1816 if ( pSdrLayer )
1818 const OUString& aLayerName = pSdrLayer->GetName();
1819 bPrintable = pSdrPageView->IsLayerPrintable( aLayerName );
1822 return bPrintable;
1826 namespace
1828 sal_Int16 CalcOutputPageNum(vcl::PDFExtOutDevData const * pPDFExtOutDevData, SdDrawDocument const *pDoc, sal_Int16 nPageNumber)
1830 //export all pages, simple one to one case
1831 if (pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides())
1832 return nPageNumber-1;
1833 //check all preceding pages, and only count non-hidden ones
1834 sal_Int16 nRet = 0;
1835 for (sal_Int16 i = 0; i < nPageNumber-1; ++i)
1837 if (!pDoc->GetSdPage(i, PageKind::Standard)->IsExcluded())
1838 ++nRet;
1840 return nRet;
1844 void SAL_CALL SdXImpressDocument::render( sal_Int32 nRenderer, const uno::Any& rSelection,
1845 const uno::Sequence< beans::PropertyValue >& rxOptions )
1847 ::SolarMutexGuard aGuard;
1849 if( nullptr == mpDoc )
1850 throw lang::DisposedException();
1852 if (!mpDocShell)
1853 return;
1855 uno::Reference< awt::XDevice > xRenderDevice;
1856 const sal_Int32 nPageNumber = nRenderer + 1;
1857 PageKind ePageKind = PageKind::Standard;
1858 bool bExportNotesPages = false;
1860 for( const auto& rOption : rxOptions )
1862 if ( rOption.Name == "RenderDevice" )
1863 rOption.Value >>= xRenderDevice;
1864 else if ( rOption.Name == "ExportNotesPages" )
1866 rOption.Value >>= bExportNotesPages;
1867 if ( bExportNotesPages )
1868 ePageKind = PageKind::Notes;
1872 if( !(xRenderDevice.is() && nPageNumber && ( nPageNumber <= mpDoc->GetSdPageCount( ePageKind ) )) )
1873 return;
1875 VCLXDevice* pDevice = comphelper::getUnoTunnelImplementation<VCLXDevice>( xRenderDevice );
1876 VclPtr< OutputDevice> pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
1878 if( !pOut )
1879 return;
1881 vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData* >( pOut->GetExtOutDevData() );
1883 if ( !(!( mpDoc->GetSdPage(static_cast<sal_Int16>(nPageNumber)-1, PageKind::Standard)->IsExcluded() ) ||
1884 (pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides())) )
1885 return;
1887 std::unique_ptr<::sd::ClientView> pView( new ::sd::ClientView( mpDocShell, pOut ) );
1888 ::tools::Rectangle aVisArea( Point(), mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind )->GetSize() );
1889 vcl::Region aRegion( aVisArea );
1891 ::sd::ViewShell* pOldViewSh = mpDocShell->GetViewShell();
1892 ::sd::View* pOldSdView = pOldViewSh ? pOldViewSh->GetView() : nullptr;
1894 if ( pOldSdView )
1895 pOldSdView->SdrEndTextEdit();
1897 pView->SetHlplVisible( false );
1898 pView->SetGridVisible( false );
1899 pView->SetBordVisible( false );
1900 pView->SetPageVisible( false );
1901 pView->SetGlueVisible( false );
1903 pOut->SetMapMode(MapMode(MapUnit::Map100thMM));
1904 pOut->IntersectClipRegion( aVisArea );
1906 uno::Reference< frame::XModel > xModel;
1907 rSelection >>= xModel;
1909 if( xModel == mpDocShell->GetModel() )
1911 pView->ShowSdrPage( mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind ));
1912 SdrPageView* pPV = pView->GetSdrPageView();
1914 if( pOldSdView )
1916 SdrPageView* pOldPV = pOldSdView->GetSdrPageView();
1917 if( pPV && pOldPV )
1919 pPV->SetVisibleLayers( pOldPV->GetVisibleLayers() );
1920 pPV->SetPrintableLayers( pOldPV->GetPrintableLayers() );
1924 ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
1925 pPV, pPDFExtOutDevData );
1927 // background color for outliner :o
1928 SdPage* pPage = pPV ? static_cast<SdPage*>(pPV->GetPage()) : nullptr;
1929 if( pPage )
1931 SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
1932 bool bScreenDisplay(true);
1934 // #i75566# printing; suppress AutoColor BackgroundColor generation
1935 // for visibility reasons by giving GetPageBackgroundColor()
1936 // the needed hint
1937 // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing)
1938 if (pOut && ((OUTDEV_PRINTER == pOut->GetOutDevType())
1939 || (OUTDEV_PDF == pOut->GetOutDevType())))
1940 bScreenDisplay = false;
1942 // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
1943 // hint value if screen display. Only then the AutoColor mechanisms shall be applied
1944 rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor( pPV, bScreenDisplay ) );
1946 pView->SdrPaintView::CompleteRedraw( pOut, aRegion, &aImplRenderPaintProc );
1948 if ( pPDFExtOutDevData && pPage )
1952 uno::Any aAny;
1953 uno::Reference< drawing::XDrawPage > xPage( uno::Reference< drawing::XDrawPage >::query( pPage->getUnoPage() ) );
1954 if ( xPage.is() )
1956 if ( pPDFExtOutDevData->GetIsExportNotes() )
1957 ImplPDFExportComments( xPage, *pPDFExtOutDevData );
1958 uno::Reference< beans::XPropertySet > xPagePropSet( xPage, uno::UNO_QUERY );
1959 if( xPagePropSet.is() )
1961 // exporting object interactions to pdf
1963 // if necessary, the master page interactions will be exported first
1964 bool bIsBackgroundObjectsVisible = false; // #i39428# IsBackgroundObjectsVisible not available for Draw
1965 if ( mbImpressDoc && xPagePropSet->getPropertySetInfo()->hasPropertyByName( "IsBackgroundObjectsVisible" ) )
1966 xPagePropSet->getPropertyValue( "IsBackgroundObjectsVisible" ) >>= bIsBackgroundObjectsVisible;
1967 if ( bIsBackgroundObjectsVisible && !pPDFExtOutDevData->GetIsExportNotesPages() )
1969 uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( xPage, uno::UNO_QUERY );
1970 if ( xMasterPageTarget.is() )
1972 uno::Reference< drawing::XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage();
1973 if ( xMasterPage.is() )
1975 sal_Int32 i, nCount = xMasterPage->getCount();
1976 for ( i = 0; i < nCount; i++ )
1978 aAny = xMasterPage->getByIndex( i );
1979 uno::Reference< drawing::XShape > xShape;
1980 if ( aAny >>= xShape )
1981 ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
1987 // exporting slide page object interactions
1988 sal_Int32 i, nCount = xPage->getCount();
1989 for ( i = 0; i < nCount; i++ )
1991 aAny = xPage->getByIndex( i );
1992 uno::Reference< drawing::XShape > xShape;
1993 if ( aAny >>= xShape )
1994 ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
1997 // exporting transition effects to pdf
1998 if ( mbImpressDoc && !pPDFExtOutDevData->GetIsExportNotesPages() && pPDFExtOutDevData->GetIsExportTransitionEffects() )
2000 const OUString sEffect( "Effect" );
2001 const OUString sSpeed ( "Speed" );
2002 sal_Int32 nTime = 800;
2003 presentation::AnimationSpeed aAs;
2004 if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
2006 aAny = xPagePropSet->getPropertyValue( sSpeed );
2007 if ( aAny >>= aAs )
2009 switch( aAs )
2011 case presentation::AnimationSpeed_SLOW : nTime = 1500; break;
2012 case presentation::AnimationSpeed_FAST : nTime = 300; break;
2013 default:
2014 case presentation::AnimationSpeed_MEDIUM : nTime = 800;
2018 presentation::FadeEffect eFe;
2019 vcl::PDFWriter::PageTransition eType = vcl::PDFWriter::PageTransition::Regular;
2020 if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) )
2022 aAny = xPagePropSet->getPropertyValue( sEffect );
2023 if ( aAny >>= eFe )
2025 switch( eFe )
2027 case presentation::FadeEffect_HORIZONTAL_LINES :
2028 case presentation::FadeEffect_HORIZONTAL_CHECKERBOARD :
2029 case presentation::FadeEffect_HORIZONTAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsHorizontal; break;
2031 case presentation::FadeEffect_VERTICAL_LINES :
2032 case presentation::FadeEffect_VERTICAL_CHECKERBOARD :
2033 case presentation::FadeEffect_VERTICAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsVertical; break;
2035 case presentation::FadeEffect_UNCOVER_TO_RIGHT :
2036 case presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT :
2037 case presentation::FadeEffect_ROLL_FROM_LEFT :
2038 case presentation::FadeEffect_FADE_FROM_UPPERLEFT :
2039 case presentation::FadeEffect_MOVE_FROM_UPPERLEFT :
2040 case presentation::FadeEffect_FADE_FROM_LEFT :
2041 case presentation::FadeEffect_MOVE_FROM_LEFT : eType = vcl::PDFWriter::PageTransition::WipeLeftToRight; break;
2043 case presentation::FadeEffect_UNCOVER_TO_BOTTOM :
2044 case presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT :
2045 case presentation::FadeEffect_ROLL_FROM_TOP :
2046 case presentation::FadeEffect_FADE_FROM_UPPERRIGHT :
2047 case presentation::FadeEffect_MOVE_FROM_UPPERRIGHT :
2048 case presentation::FadeEffect_FADE_FROM_TOP :
2049 case presentation::FadeEffect_MOVE_FROM_TOP : eType = vcl::PDFWriter::PageTransition::WipeTopToBottom; break;
2051 case presentation::FadeEffect_UNCOVER_TO_LEFT :
2052 case presentation::FadeEffect_UNCOVER_TO_LOWERLEFT :
2053 case presentation::FadeEffect_ROLL_FROM_RIGHT :
2055 case presentation::FadeEffect_FADE_FROM_LOWERRIGHT :
2056 case presentation::FadeEffect_MOVE_FROM_LOWERRIGHT :
2057 case presentation::FadeEffect_FADE_FROM_RIGHT :
2058 case presentation::FadeEffect_MOVE_FROM_RIGHT : eType = vcl::PDFWriter::PageTransition::WipeRightToLeft; break;
2060 case presentation::FadeEffect_UNCOVER_TO_TOP :
2061 case presentation::FadeEffect_UNCOVER_TO_UPPERLEFT :
2062 case presentation::FadeEffect_ROLL_FROM_BOTTOM :
2063 case presentation::FadeEffect_FADE_FROM_LOWERLEFT :
2064 case presentation::FadeEffect_MOVE_FROM_LOWERLEFT :
2065 case presentation::FadeEffect_FADE_FROM_BOTTOM :
2066 case presentation::FadeEffect_MOVE_FROM_BOTTOM : eType = vcl::PDFWriter::PageTransition::WipeBottomToTop; break;
2068 case presentation::FadeEffect_OPEN_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalInward; break;
2069 case presentation::FadeEffect_CLOSE_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalOutward; break;
2071 case presentation::FadeEffect_OPEN_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalInward; break;
2072 case presentation::FadeEffect_CLOSE_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalOutward; break;
2074 case presentation::FadeEffect_FADE_TO_CENTER : eType = vcl::PDFWriter::PageTransition::BoxInward; break;
2075 case presentation::FadeEffect_FADE_FROM_CENTER : eType = vcl::PDFWriter::PageTransition::BoxOutward; break;
2077 case presentation::FadeEffect_NONE : eType = vcl::PDFWriter::PageTransition::Regular; break;
2079 case presentation::FadeEffect_RANDOM :
2080 case presentation::FadeEffect_DISSOLVE :
2081 default: eType = vcl::PDFWriter::PageTransition::Dissolve; break;
2086 if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) ||
2087 xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
2089 pPDFExtOutDevData->SetPageTransition( eType, nTime );
2095 Size aPageSize( mpDoc->GetSdPage( 0, PageKind::Standard )->GetSize() );
2096 Point aPoint( 0, 0 );
2097 ::tools::Rectangle aPageRect( aPoint, aPageSize );
2099 // resolving links found in this page by the method ImpEditEngine::Paint
2100 std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
2101 for ( const auto& rBookmark : rBookmarks )
2103 sal_Int32 nPage = ImplPDFGetBookmarkPage( rBookmark.aBookmark, *mpDoc );
2104 if ( nPage != -1 )
2106 if ( rBookmark.nLinkId != -1 )
2107 pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, pPDFExtOutDevData->CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle ) );
2108 else
2109 pPDFExtOutDevData->DescribeRegisteredDest( rBookmark.nDestId, aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle );
2111 else
2112 pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, rBookmark.aBookmark );
2114 rBookmarks.clear();
2115 //---> #i56629, #i40318
2116 //get the page name, will be used as outline element in PDF bookmark pane
2117 OUString aPageName = mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1 , PageKind::Standard )->GetName();
2118 if( !aPageName.isEmpty() )
2120 // Destination PageNum
2121 const sal_Int32 nDestPageNum = CalcOutputPageNum(pPDFExtOutDevData, mpDoc, nPageNumber);
2123 // insert the bookmark to this page into the NamedDestinations
2124 if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
2125 pPDFExtOutDevData->CreateNamedDest(aPageName, aPageRect, nDestPageNum);
2127 // add the name to the outline, (almost) same code as in sc/source/ui/unoobj/docuno.cxx
2128 // issue #i40318.
2130 if( pPDFExtOutDevData->GetIsExportBookmarks() )
2132 // Destination Export
2133 const sal_Int32 nDestId =
2134 pPDFExtOutDevData->CreateDest(aPageRect , nDestPageNum);
2136 // Create a new outline item:
2137 pPDFExtOutDevData->CreateOutlineItem( -1 , aPageName, nDestId );
2140 //<--- #i56629, #i40318
2142 catch (const uno::Exception&)
2148 else
2150 uno::Reference< drawing::XShapes > xShapes;
2151 rSelection >>= xShapes;
2153 if( xShapes.is() && xShapes->getCount() )
2155 SdrPageView* pPV = nullptr;
2157 ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
2158 pOldSdView ? pOldSdView->GetSdrPageView() : nullptr, pPDFExtOutDevData );
2160 for( sal_uInt32 i = 0, nCount = xShapes->getCount(); i < nCount; i++ )
2162 uno::Reference< drawing::XShape > xShape;
2163 xShapes->getByIndex( i ) >>= xShape;
2165 if( xShape.is() )
2167 SvxShape* pShape = comphelper::getUnoTunnelImplementation<SvxShape>( xShape );
2169 if( pShape )
2171 SdrObject* pObj = pShape->GetSdrObject();
2172 if( pObj && pObj->getSdrPageFromSdrObject()
2173 && aImplRenderPaintProc.IsVisible( pObj )
2174 && aImplRenderPaintProc.IsPrintable( pObj ) )
2176 if( !pPV )
2177 pPV = pView->ShowSdrPage( pObj->getSdrPageFromSdrObject() );
2179 if( pPV )
2180 pView->MarkObj( pObj, pPV );
2185 pView->DrawMarkedObj(*pOut);
2190 DrawViewShell* SdXImpressDocument::GetViewShell()
2192 DrawViewShell* pViewSh = dynamic_cast<DrawViewShell*>(mpDocShell->GetViewShell());
2193 if (!pViewSh)
2195 SAL_WARN("sd", "DrawViewShell not available!");
2196 return nullptr;
2198 return pViewSh;
2201 void SdXImpressDocument::paintTile( VirtualDevice& rDevice,
2202 int nOutputWidth, int nOutputHeight,
2203 int nTilePosX, int nTilePosY,
2204 long nTileWidth, long nTileHeight )
2206 DrawViewShell* pViewSh = GetViewShell();
2207 if (!pViewSh)
2208 return;
2210 // Scaling. Must convert from pixels to twips. We know
2211 // that VirtualDevices use a DPI of 96.
2212 // We specifically calculate these scales first as we're still
2213 // in TWIPs, and might as well minimize the number of conversions.
2214 Fraction scaleX = Fraction( nOutputWidth, 96 ) * Fraction(1440) /
2215 Fraction( nTileWidth);
2216 Fraction scaleY = Fraction( nOutputHeight, 96 ) * Fraction(1440) /
2217 Fraction( nTileHeight);
2219 // svx seems to be the only component that works natively in
2220 // 100th mm rather than TWIP. It makes most sense just to
2221 // convert here and in getDocumentSize, and leave the tiled
2222 // rendering API working in TWIPs.
2223 long nTileWidthHMM = convertTwipToMm100( nTileWidth );
2224 long nTileHeightHMM = convertTwipToMm100( nTileHeight );
2225 int nTilePosXHMM = convertTwipToMm100( nTilePosX );
2226 int nTilePosYHMM = convertTwipToMm100( nTilePosY );
2228 MapMode aMapMode = rDevice.GetMapMode();
2229 aMapMode.SetMapUnit( MapUnit::Map100thMM );
2230 aMapMode.SetOrigin( Point( -nTilePosXHMM,
2231 -nTilePosYHMM) );
2232 aMapMode.SetScaleX( scaleX );
2233 aMapMode.SetScaleY( scaleY );
2235 rDevice.SetMapMode( aMapMode );
2237 rDevice.SetOutputSizePixel( Size(nOutputWidth, nOutputHeight) );
2239 Point aPoint(nTilePosXHMM, nTilePosYHMM);
2240 Size aSize(nTileWidthHMM, nTileHeightHMM);
2241 ::tools::Rectangle aRect(aPoint, aSize);
2243 pViewSh->GetView()->CompleteRedraw(&rDevice, vcl::Region(aRect));
2245 LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
2246 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2249 void SdXImpressDocument::selectPart(int nPart, int nSelect)
2251 DrawViewShell* pViewSh = GetViewShell();
2252 if (!pViewSh)
2253 return;
2255 pViewSh->SelectPage(nPart, nSelect);
2258 void SdXImpressDocument::moveSelectedParts(int nPosition, bool bDuplicate)
2260 // Duplicating is currently unsupported.
2261 if (!bDuplicate)
2262 mpDoc->MovePages(nPosition);
2265 OUString SdXImpressDocument::getPartInfo(int nPart)
2267 DrawViewShell* pViewSh = GetViewShell();
2268 if (!pViewSh)
2269 return OUString();
2271 const bool bIsVisible = pViewSh->IsVisible(nPart);
2272 const bool bIsSelected = pViewSh->IsSelected(nPart);
2274 OUString aPartInfo = "{ \"visible\": \"" +
2275 OUString::number(static_cast<unsigned int>(bIsVisible)) +
2276 "\", \"selected\": \"" +
2277 OUString::number(static_cast<unsigned int>(bIsSelected)) +
2278 "\" }";
2279 return aPartInfo;
2282 void SdXImpressDocument::setPart( int nPart )
2284 DrawViewShell* pViewSh = GetViewShell();
2285 if (!pViewSh)
2286 return;
2288 pViewSh->SwitchPage( nPart );
2291 int SdXImpressDocument::getParts()
2293 // TODO: master pages?
2294 // Read: drviews1.cxx
2295 return mpDoc->GetSdPageCount(PageKind::Standard);
2298 int SdXImpressDocument::getPart()
2300 DrawViewShell* pViewSh = GetViewShell();
2301 if (!pViewSh)
2302 return 0;
2304 return pViewSh->GetViewShellBase().getPart();
2307 OUString SdXImpressDocument::getPartName( int nPart )
2309 SdPage* pPage = mpDoc->GetSdPage( nPart, PageKind::Standard );
2310 if (!pPage)
2312 SAL_WARN("sd", "DrawViewShell not available!");
2313 return OUString();
2316 return pPage->GetName();
2319 OUString SdXImpressDocument::getPartHash( int nPart )
2321 SdPage* pPage = mpDoc->GetSdPage( nPart, PageKind::Standard );
2322 if (!pPage)
2324 SAL_WARN("sd", "DrawViewShell not available!");
2325 return OUString();
2328 return OUString::number(pPage->GetHashCode());
2331 VclPtr<vcl::Window> SdXImpressDocument::getDocWindow()
2333 SolarMutexGuard aGuard;
2334 DrawViewShell* pViewShell = GetViewShell();
2335 VclPtr<vcl::Window> pWindow;
2336 if (pViewShell)
2337 pWindow = pViewShell->GetActiveWindow();
2339 LokChartHelper aChartHelper(pViewShell->GetViewShell());
2340 VclPtr<vcl::Window> pChartWindow = aChartHelper.GetWindow();
2341 if (pChartWindow)
2342 pWindow = pChartWindow;
2344 return pWindow;
2347 void SdXImpressDocument::setPartMode( int nPartMode )
2349 DrawViewShell* pViewSh = GetViewShell();
2350 if (!pViewSh)
2351 return;
2353 PageKind aPageKind( PageKind::Standard );
2354 switch ( nPartMode )
2356 case LOK_PARTMODE_SLIDES:
2357 break;
2358 case LOK_PARTMODE_NOTES:
2359 aPageKind = PageKind::Notes;
2360 break;
2362 pViewSh->SetPageKind( aPageKind );
2365 Size SdXImpressDocument::getDocumentSize()
2367 DrawViewShell* pViewSh = GetViewShell();
2368 if (!pViewSh)
2369 return Size();
2371 SdrView *pSdrView = pViewSh->GetView();
2372 if (!pSdrView)
2373 return Size();
2375 SdrPageView* pCurPageView = pSdrView->GetSdrPageView();
2376 if (!pCurPageView)
2377 return Size();
2379 Size aSize = pCurPageView->GetPageRect().GetSize();
2380 // Convert the size in 100th mm to TWIP
2381 // See paintTile above for further info.
2382 return Size(convertMm100ToTwip(aSize.getWidth()), convertMm100ToTwip(aSize.getHeight()));
2385 OUString SdXImpressDocument::getPostIts()
2387 boost::property_tree::ptree aAnnotations;
2388 // Return annotations on master pages too ?
2389 const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
2390 SdPage* pPage;
2391 for (sal_uInt16 nPage = 0; nPage < nMaxPages; ++nPage)
2393 pPage = static_cast<SdPage*>(mpDoc->GetPage(nPage));
2394 const sd::AnnotationVector& aPageAnnotations = pPage->getAnnotations();
2396 for (const uno::Reference<office::XAnnotation>& xAnnotation : aPageAnnotations)
2398 boost::property_tree::ptree aAnnotation;
2399 aAnnotation.put("id", sd::getAnnotationId(xAnnotation));
2400 aAnnotation.put("author", xAnnotation->getAuthor());
2401 aAnnotation.put("dateTime", utl::toISO8601(xAnnotation->getDateTime()));
2402 uno::Reference<text::XText> xText(xAnnotation->getTextRange());
2403 aAnnotation.put("text", xText->getString());
2404 aAnnotation.put("parthash", OUString(OUString::number(pPage->GetHashCode())));
2406 aAnnotations.push_back(std::make_pair("", aAnnotation));
2410 boost::property_tree::ptree aTree;
2411 aTree.add_child("comments", aAnnotations);
2412 std::stringstream aStream;
2413 boost::property_tree::write_json(aStream, aTree);
2415 return OUString::fromUtf8(aStream.str().c_str());
2418 void SdXImpressDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
2420 SolarMutexGuard aGuard;
2422 if (DrawViewShell* pViewShell = GetViewShell())
2424 DrawView* pDrawView = pViewShell->GetDrawView();
2425 for (const beans::PropertyValue& rValue : rArguments)
2427 if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
2428 pDrawView->SetPageShadowVisible(rValue.Value.get<bool>());
2429 else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
2430 pDrawView->SetAuthor(rValue.Value.get<OUString>());
2433 // Disable comments if requested
2434 SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
2435 pOptions->SetShowComments(comphelper::LibreOfficeKit::isTiledAnnotations());
2437 pViewShell->SetRuler(false);
2438 pViewShell->SetScrollBarsVisible(false);
2440 if (sd::Window* pWindow = pViewShell->GetActiveWindow())
2442 // get the full page size in pixels
2443 pWindow->EnableMapMode();
2444 Size aSize(pWindow->LogicToPixel(pDrawView->GetSdrPageView()->GetPage()->GetSize()));
2445 // Disable map mode, so that it's possible to send mouse event
2446 // coordinates in logic units
2447 pWindow->EnableMapMode(false);
2449 // arrange UI elements again with new view size
2450 pViewShell->GetParentWindow()->SetSizePixel(aSize);
2451 pViewShell->Resize();
2454 // Forces all images to be swapped in synchronously, this
2455 // ensures that images are available when paintTile is called
2456 // (whereas with async loading images start being loaded after
2457 // we have painted the tile, resulting in an invalidate, followed
2458 // by the tile being rerendered - which is wasteful and ugly).
2459 pDrawView->SetSwapAsynchron(false);
2462 // when the "This document may contain formatting or content that cannot
2463 // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
2464 // causing 'Save' being disabled; so let's always save to the original
2465 // format
2466 SvtSaveOptions().SetWarnAlienFormat(false);
2469 void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
2471 SolarMutexGuard aGuard;
2472 SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
2475 void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
2477 SolarMutexGuard aGuard;
2479 DrawViewShell* pViewShell = GetViewShell();
2480 if (!pViewShell)
2481 return;
2483 double fScale = 1.0/TWIPS_PER_PIXEL;
2485 // check if user hit a chart which is being edited by him
2486 LokChartHelper aChartHelper(pViewShell->GetViewShell());
2487 if (aChartHelper.postMouseEvent(nType, nX, nY,
2488 nCount, nButtons, nModifier,
2489 fScale, fScale))
2490 return;
2492 // check if the user hit a chart which is being edited by someone else
2493 // and, if so, skip current mouse event
2494 if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
2496 if (LokChartHelper::HitAny(Point(nX, nY)))
2497 return;
2500 const Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)));
2501 SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), nType,
2502 aPos, nCount,
2503 MouseEventModifiers::SIMPLECLICK,
2504 nButtons, nModifier);
2507 void SdXImpressDocument::setTextSelection(int nType, int nX, int nY)
2509 SolarMutexGuard aGuard;
2511 DrawViewShell* pViewShell = GetViewShell();
2512 if (!pViewShell)
2513 return;
2515 LokChartHelper aChartHelper(pViewShell->GetViewShell());
2516 if (aChartHelper.setTextSelection(nType, nX, nY))
2517 return;
2519 Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
2520 switch (nType)
2522 case LOK_SETTEXTSELECTION_START:
2523 pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
2524 break;
2525 case LOK_SETTEXTSELECTION_END:
2526 pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
2527 break;
2528 case LOK_SETTEXTSELECTION_RESET:
2529 pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
2530 break;
2531 default:
2532 assert(false);
2533 break;
2537 uno::Reference<datatransfer::XTransferable> SdXImpressDocument::getSelection()
2539 SolarMutexGuard aGuard;
2541 DrawViewShell* pViewShell = GetViewShell();
2542 if (!pViewShell)
2543 return uno::Reference<datatransfer::XTransferable>();
2545 return pViewShell->GetSelectionTransferrable();
2548 void SdXImpressDocument::setGraphicSelection(int nType, int nX, int nY)
2550 SolarMutexGuard aGuard;
2552 DrawViewShell* pViewShell = GetViewShell();
2553 if (!pViewShell)
2554 return;
2556 double fScale = 1.0/TWIPS_PER_PIXEL;
2558 LokChartHelper aChartHelper(pViewShell->GetViewShell());
2559 if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
2560 return;
2562 Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
2563 switch (nType)
2565 case LOK_SETGRAPHICSELECTION_START:
2566 pViewShell->SetGraphicMm100Position(/*bStart=*/true, aPoint);
2567 break;
2568 case LOK_SETGRAPHICSELECTION_END:
2569 pViewShell->SetGraphicMm100Position(/*bStart=*/false, aPoint);
2570 break;
2571 default:
2572 assert(false);
2573 break;
2577 void SdXImpressDocument::resetSelection()
2579 SolarMutexGuard aGuard;
2581 DrawViewShell* pViewShell = GetViewShell();
2582 if (!pViewShell)
2583 return;
2585 SdrView* pSdrView = pViewShell->GetView();
2586 if (!pSdrView)
2587 return;
2589 if (pSdrView->IsTextEdit())
2591 // Reset the editeng selection.
2592 pSdrView->UnmarkAll();
2593 // Finish editing.
2594 pSdrView->SdrEndTextEdit();
2596 // Reset graphic selection.
2597 pSdrView->UnmarkAll();
2600 void SdXImpressDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
2602 SolarMutexGuard aGuard;
2604 DrawViewShell* pViewShell = GetViewShell();
2605 if (!pViewShell)
2606 return;
2608 pViewShell->GetActiveWindow()->SetClipboard(xClipboard);
2611 bool SdXImpressDocument::isMimeTypeSupported()
2613 SolarMutexGuard aGuard;
2614 DrawViewShell* pViewShell = GetViewShell();
2615 if (!pViewShell)
2616 return false;
2618 TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewShell->GetActiveWindow()));
2619 return EditEngine::HasValidData(aDataHelper.GetTransferable());
2622 PointerStyle SdXImpressDocument::getPointer()
2624 SolarMutexGuard aGuard;
2625 DrawViewShell* pViewShell = GetViewShell();
2626 if (!pViewShell)
2627 return PointerStyle::Arrow;
2629 Window* pWindow = pViewShell->GetActiveWindow();
2630 if (!pWindow)
2631 return PointerStyle::Arrow;
2633 return pWindow->GetPointer();
2636 uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable()
2638 uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbiddenCharacters);
2640 if( !xForb.is() )
2641 mxForbiddenCharacters = xForb = new SdUnoForbiddenCharsTable( mpDoc );
2643 return xForb;
2646 void SdXImpressDocument::initializeDocument()
2648 if( mbClipBoard )
2649 return;
2651 switch( mpDoc->GetPageCount() )
2653 case 1:
2655 // nasty hack to detect clipboard document
2656 mbClipBoard = true;
2657 break;
2659 case 0:
2661 mpDoc->CreateFirstPages();
2662 mpDoc->StopWorkStartupDelay();
2663 break;
2668 SdrModel& SdXImpressDocument::getSdrModelFromUnoModel() const
2670 OSL_ENSURE(GetDoc(), "No SdrModel in draw/Impress, should not happen");
2671 return *GetDoc(); // TTTT should be reference
2674 void SAL_CALL SdXImpressDocument::dispose()
2676 if( mbDisposed )
2677 return;
2679 ::SolarMutexGuard aGuard;
2681 if( mpDoc )
2683 EndListening( *mpDoc );
2684 mpDoc = nullptr;
2687 // Call the base class dispose() before setting the mbDisposed flag
2688 // to true. The reason for this is that if close() has not yet been
2689 // called this is done in SfxBaseModel::dispose(). At the end of
2690 // that dispose() is called again. It is important to forward this
2691 // second dispose() to the base class, too.
2692 // As a consequence the following code has to be able to be run twice.
2693 SfxBaseModel::dispose();
2694 mbDisposed = true;
2696 uno::Reference< container::XNameAccess > xLinks( mxLinks );
2697 if( xLinks.is() )
2699 uno::Reference< lang::XComponent > xComp( xLinks, uno::UNO_QUERY );
2700 if( xComp.is() )
2701 xComp->dispose();
2703 xLinks = nullptr;
2706 uno::Reference< drawing::XDrawPages > xDrawPagesAccess( mxDrawPagesAccess );
2707 if( xDrawPagesAccess.is() )
2709 uno::Reference< lang::XComponent > xComp( xDrawPagesAccess, uno::UNO_QUERY );
2710 if( xComp.is() )
2711 xComp->dispose();
2713 xDrawPagesAccess = nullptr;
2716 uno::Reference< drawing::XDrawPages > xMasterPagesAccess( mxMasterPagesAccess );
2717 if( xDrawPagesAccess.is() )
2719 uno::Reference< lang::XComponent > xComp( xMasterPagesAccess, uno::UNO_QUERY );
2720 if( xComp.is() )
2721 xComp->dispose();
2723 xDrawPagesAccess = nullptr;
2726 uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager );
2727 if( xLayerManager.is() )
2729 uno::Reference< lang::XComponent > xComp( xLayerManager, uno::UNO_QUERY );
2730 if( xComp.is() )
2731 xComp->dispose();
2733 xLayerManager = nullptr;
2736 uno::Reference< container::XNameContainer > xCustomPresentationAccess( mxCustomPresentationAccess );
2737 if( xCustomPresentationAccess.is() )
2739 uno::Reference< lang::XComponent > xComp( xCustomPresentationAccess, uno::UNO_QUERY );
2740 if( xComp.is() )
2741 xComp->dispose();
2743 xCustomPresentationAccess = nullptr;
2746 mxDashTable = nullptr;
2747 mxGradientTable = nullptr;
2748 mxHatchTable = nullptr;
2749 mxBitmapTable = nullptr;
2750 mxTransGradientTable = nullptr;
2751 mxMarkerTable = nullptr;
2752 mxDrawingPool = nullptr;
2755 // class SdDrawPagesAccess
2757 SdDrawPagesAccess::SdDrawPagesAccess( SdXImpressDocument& rMyModel ) throw()
2758 : mpModel( &rMyModel)
2762 SdDrawPagesAccess::~SdDrawPagesAccess() throw()
2766 // XIndexAccess
2767 sal_Int32 SAL_CALL SdDrawPagesAccess::getCount()
2769 ::SolarMutexGuard aGuard;
2771 if( nullptr == mpModel )
2772 throw lang::DisposedException();
2774 return mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2777 uno::Any SAL_CALL SdDrawPagesAccess::getByIndex( sal_Int32 Index )
2779 ::SolarMutexGuard aGuard;
2781 if( nullptr == mpModel )
2782 throw lang::DisposedException();
2784 uno::Any aAny;
2786 if( (Index < 0) || (Index >= mpModel->mpDoc->GetSdPageCount( PageKind::Standard ) ) )
2787 throw lang::IndexOutOfBoundsException();
2789 SdPage* pPage = mpModel->mpDoc->GetSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
2790 if( pPage )
2792 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2793 aAny <<= xDrawPage;
2796 return aAny;
2799 // XNameAccess
2800 uno::Any SAL_CALL SdDrawPagesAccess::getByName( const OUString& aName )
2802 ::SolarMutexGuard aGuard;
2804 if( nullptr == mpModel )
2805 throw lang::DisposedException();
2807 if( !aName.isEmpty() )
2809 const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2810 sal_uInt16 nPage;
2811 for( nPage = 0; nPage < nCount; nPage++ )
2813 SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2814 if(nullptr == pPage)
2815 continue;
2817 if( aName == SdDrawPage::getPageApiName( pPage ) )
2819 uno::Any aAny;
2820 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2821 aAny <<= xDrawPage;
2822 return aAny;
2827 throw container::NoSuchElementException();
2830 uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getElementNames()
2832 ::SolarMutexGuard aGuard;
2834 if( nullptr == mpModel )
2835 throw lang::DisposedException();
2837 const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2838 uno::Sequence< OUString > aNames( nCount );
2839 OUString* pNames = aNames.getArray();
2841 sal_uInt16 nPage;
2842 for( nPage = 0; nPage < nCount; nPage++ )
2844 SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2845 *pNames++ = SdDrawPage::getPageApiName( pPage );
2848 return aNames;
2851 sal_Bool SAL_CALL SdDrawPagesAccess::hasByName( const OUString& aName )
2853 ::SolarMutexGuard aGuard;
2855 if( nullptr == mpModel )
2856 throw lang::DisposedException();
2858 const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2859 sal_uInt16 nPage;
2860 for( nPage = 0; nPage < nCount; nPage++ )
2862 SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2863 if(nullptr == pPage)
2864 continue;
2866 if( aName == SdDrawPage::getPageApiName( pPage ) )
2867 return true;
2870 return false;
2873 // XElementAccess
2874 uno::Type SAL_CALL SdDrawPagesAccess::getElementType()
2876 return cppu::UnoType<drawing::XDrawPage>::get();
2879 sal_Bool SAL_CALL SdDrawPagesAccess::hasElements()
2881 return getCount() > 0;
2884 // XDrawPages
2887 * Creates a new page with model at the specified position.
2888 * @returns corresponding SdDrawPage
2890 uno::Reference< drawing::XDrawPage > SAL_CALL SdDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex )
2892 ::SolarMutexGuard aGuard;
2893 comphelper::ProfileZone aZone("insertNewByIndex");
2895 if( nullptr == mpModel )
2896 throw lang::DisposedException();
2898 if( mpModel->mpDoc )
2900 SdPage* pPage = mpModel->InsertSdPage( static_cast<sal_uInt16>(nIndex), false );
2901 if( pPage )
2903 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2904 return xDrawPage;
2907 uno::Reference< drawing::XDrawPage > xDrawPage;
2908 return xDrawPage;
2912 * Removes the specified SdDrawPage from the model and the internal list. It
2913 * only works, if there is at least one *normal* page in the model after
2914 * removing this page.
2916 void SAL_CALL SdDrawPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
2918 ::SolarMutexGuard aGuard;
2920 if( nullptr == mpModel || mpModel->mpDoc == nullptr )
2921 throw lang::DisposedException();
2923 SdDrawDocument& rDoc = *mpModel->mpDoc;
2925 sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard );
2926 if( nPageCount > 1 )
2928 // get pPage from xPage and determine the Id (nPos ) afterwards
2929 SdDrawPage* pSvxPage = comphelper::getUnoTunnelImplementation<SdDrawPage>( xPage );
2930 if( pSvxPage )
2932 SdPage* pPage = static_cast<SdPage*>(pSvxPage->GetSdrPage());
2933 if(pPage && ( pPage->GetPageKind() == PageKind::Standard ) )
2935 sal_uInt16 nPage = pPage->GetPageNum();
2937 SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetPage( nPage+1 ) );
2939 bool bUndo = rDoc.IsUndoEnabled();
2940 if( bUndo )
2942 // Add undo actions and delete the pages. The order of adding
2943 // the undo actions is important.
2944 rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
2945 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
2946 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
2949 rDoc.RemovePage( nPage ); // the page
2950 rDoc.RemovePage( nPage ); // the notes page
2952 if( bUndo )
2954 rDoc.EndUndo();
2956 else
2958 delete pNotesPage;
2959 delete pPage;
2965 mpModel->SetModified();
2968 // XServiceInfo
2970 OUString SAL_CALL SdDrawPagesAccess::getImplementationName( )
2972 return "SdDrawPagesAccess";
2975 sal_Bool SAL_CALL SdDrawPagesAccess::supportsService( const OUString& ServiceName )
2977 return cppu::supportsService(this, ServiceName);
2980 uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getSupportedServiceNames( )
2982 return { "com.sun.star.drawing.DrawPages" };
2985 // XComponent
2986 void SAL_CALL SdDrawPagesAccess::dispose( )
2988 mpModel = nullptr;
2991 void SAL_CALL SdDrawPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >& )
2993 OSL_FAIL( "not implemented!" );
2996 void SAL_CALL SdDrawPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >& )
2998 OSL_FAIL( "not implemented!" );
3001 // class SdMasterPagesAccess
3003 SdMasterPagesAccess::SdMasterPagesAccess( SdXImpressDocument& rMyModel ) throw()
3004 : mpModel(&rMyModel)
3008 SdMasterPagesAccess::~SdMasterPagesAccess() throw()
3012 // XComponent
3013 void SAL_CALL SdMasterPagesAccess::dispose( )
3015 mpModel = nullptr;
3018 void SAL_CALL SdMasterPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >& )
3020 OSL_FAIL( "not implemented!" );
3023 void SAL_CALL SdMasterPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >& )
3025 OSL_FAIL( "not implemented!" );
3028 // XIndexAccess
3029 sal_Int32 SAL_CALL SdMasterPagesAccess::getCount()
3031 ::SolarMutexGuard aGuard;
3033 if( nullptr == mpModel->mpDoc )
3034 throw lang::DisposedException();
3036 return mpModel->mpDoc->GetMasterSdPageCount(PageKind::Standard);
3040 * Provides a drawing::XDrawPage interface for accessing the Masterpage at the
3041 * specified position in the model.
3043 uno::Any SAL_CALL SdMasterPagesAccess::getByIndex( sal_Int32 Index )
3045 ::SolarMutexGuard aGuard;
3046 comphelper::ProfileZone aZone("SdMasterPagesAccess::getByIndex");
3048 if( nullptr == mpModel )
3049 throw lang::DisposedException();
3051 uno::Any aAny;
3053 if( (Index < 0) || (Index >= mpModel->mpDoc->GetMasterSdPageCount( PageKind::Standard ) ) )
3054 throw lang::IndexOutOfBoundsException();
3056 SdPage* pPage = mpModel->mpDoc->GetMasterSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
3057 if( pPage )
3059 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
3060 aAny <<= xDrawPage;
3063 return aAny;
3066 // XElementAccess
3067 uno::Type SAL_CALL SdMasterPagesAccess::getElementType()
3069 return cppu::UnoType<drawing::XDrawPage>::get();
3072 sal_Bool SAL_CALL SdMasterPagesAccess::hasElements()
3074 return getCount() > 0;
3077 // XDrawPages
3078 uno::Reference< drawing::XDrawPage > SAL_CALL SdMasterPagesAccess::insertNewByIndex( sal_Int32 nInsertPos )
3080 ::SolarMutexGuard aGuard;
3082 if( nullptr == mpModel )
3083 throw lang::DisposedException();
3085 uno::Reference< drawing::XDrawPage > xDrawPage;
3087 SdDrawDocument* pDoc = mpModel->mpDoc;
3088 if( pDoc )
3090 // calculate internal index and check for range errors
3091 const sal_Int32 nMPageCount = pDoc->GetMasterPageCount();
3092 nInsertPos = nInsertPos * 2 + 1;
3093 if( nInsertPos < 0 || nInsertPos > nMPageCount )
3094 nInsertPos = nMPageCount;
3096 // now generate a unique name for the new masterpage
3097 const OUString aStdPrefix( SdResId(STR_LAYOUT_DEFAULT_NAME) );
3098 OUString aPrefix( aStdPrefix );
3100 bool bUnique = true;
3102 std::vector<OUString> aPageNames;
3103 for (sal_Int32 nMaster = 1; nMaster < nMPageCount; ++nMaster)
3105 const SdPage* pPage = static_cast<const SdPage*>(pDoc->GetMasterPage(static_cast<sal_uInt16>(nMaster)));
3106 if (!pPage)
3107 continue;
3108 aPageNames.push_back(pPage->GetName());
3109 if (aPageNames.back() == aPrefix)
3110 bUnique = false;
3113 sal_Int32 i = 0;
3114 while (!bUnique)
3116 aPrefix = aStdPrefix + " " + OUString::number(++i);
3117 bUnique = std::find(aPageNames.begin(), aPageNames.end(), aPrefix) == aPageNames.end();
3120 OUString aLayoutName = aPrefix + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
3122 // create styles
3123 static_cast<SdStyleSheetPool*>(pDoc->GetStyleSheetPool())->CreateLayoutStyleSheets( aPrefix );
3125 // get the first page for initial size and border settings
3126 SdPage* pPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Standard );
3127 SdPage* pRefNotesPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Notes);
3129 // create and insert new draw masterpage
3130 SdPage* pMPage = mpModel->mpDoc->AllocSdPage(true);
3131 pMPage->SetSize( pPage->GetSize() );
3132 pMPage->SetBorder( pPage->GetLeftBorder(),
3133 pPage->GetUpperBorder(),
3134 pPage->GetRightBorder(),
3135 pPage->GetLowerBorder() );
3136 pMPage->SetLayoutName( aLayoutName );
3137 pDoc->InsertMasterPage(pMPage, static_cast<sal_uInt16>(nInsertPos));
3140 // ensure default MasterPage fill
3141 pMPage->EnsureMasterPageDefaultBackground();
3144 xDrawPage.set( pMPage->getUnoPage(), uno::UNO_QUERY );
3146 // create and insert new notes masterpage
3147 SdPage* pMNotesPage = mpModel->mpDoc->AllocSdPage(true);
3148 pMNotesPage->SetSize( pRefNotesPage->GetSize() );
3149 pMNotesPage->SetPageKind(PageKind::Notes);
3150 pMNotesPage->SetBorder( pRefNotesPage->GetLeftBorder(),
3151 pRefNotesPage->GetUpperBorder(),
3152 pRefNotesPage->GetRightBorder(),
3153 pRefNotesPage->GetLowerBorder() );
3154 pMNotesPage->SetLayoutName( aLayoutName );
3155 pDoc->InsertMasterPage(pMNotesPage, static_cast<sal_uInt16>(nInsertPos) + 1);
3156 pMNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
3157 mpModel->SetModified();
3160 return xDrawPage;
3164 * Removes the specified SdMasterPage from the model and the internal list. It
3165 * only works, if there is no *normal* page using this page as MasterPage in
3166 * the model.
3168 void SAL_CALL SdMasterPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
3170 ::SolarMutexGuard aGuard;
3172 if( nullptr == mpModel || mpModel->mpDoc == nullptr )
3173 throw lang::DisposedException();
3175 SdMasterPage* pSdPage = comphelper::getUnoTunnelImplementation<SdMasterPage>( xPage );
3176 if(pSdPage == nullptr)
3177 return;
3179 SdPage* pPage = dynamic_cast< SdPage* > (pSdPage->GetSdrPage());
3181 DBG_ASSERT( pPage && pPage->IsMasterPage(), "SdMasterPage is not masterpage?");
3183 if( !pPage || !pPage->IsMasterPage() || (mpModel->mpDoc->GetMasterPageUserCount(pPage) > 0))
3184 return; //Todo: this should be excepted
3186 // only standard pages can be removed directly
3187 if( pPage->GetPageKind() != PageKind::Standard )
3188 return;
3190 sal_uInt16 nPage = pPage->GetPageNum();
3192 SdDrawDocument& rDoc = *mpModel->mpDoc;
3194 SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetMasterPage( nPage+1 ) );
3196 bool bUndo = rDoc.IsUndoEnabled();
3197 if( bUndo )
3199 // Add undo actions and delete the pages. The order of adding
3200 // the undo actions is important.
3201 rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
3202 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
3203 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
3206 // remove both pages
3207 rDoc.RemoveMasterPage( nPage );
3208 rDoc.RemoveMasterPage( nPage );
3210 if( bUndo )
3212 rDoc.EndUndo();
3214 else
3216 delete pNotesPage;
3217 delete pPage;
3221 // XServiceInfo
3223 OUString SAL_CALL SdMasterPagesAccess::getImplementationName( )
3225 return "SdMasterPagesAccess";
3228 sal_Bool SAL_CALL SdMasterPagesAccess::supportsService( const OUString& ServiceName )
3230 return cppu::supportsService(this, ServiceName);
3233 uno::Sequence< OUString > SAL_CALL SdMasterPagesAccess::getSupportedServiceNames( )
3235 return { "com.sun.star.drawing.MasterPages" };
3238 // class SdDocLinkTargets
3240 SdDocLinkTargets::SdDocLinkTargets( SdXImpressDocument& rMyModel ) throw()
3241 : mpModel( &rMyModel )
3245 SdDocLinkTargets::~SdDocLinkTargets() throw()
3249 // XComponent
3250 void SAL_CALL SdDocLinkTargets::dispose( )
3252 mpModel = nullptr;
3255 void SAL_CALL SdDocLinkTargets::addEventListener( const uno::Reference< lang::XEventListener >& )
3257 OSL_FAIL( "not implemented!" );
3260 void SAL_CALL SdDocLinkTargets::removeEventListener( const uno::Reference< lang::XEventListener >& )
3262 OSL_FAIL( "not implemented!" );
3265 // XNameAccess
3266 uno::Any SAL_CALL SdDocLinkTargets::getByName( const OUString& aName )
3268 ::SolarMutexGuard aGuard;
3270 if( nullptr == mpModel )
3271 throw lang::DisposedException();
3273 SdPage* pPage = FindPage( aName );
3275 if( pPage == nullptr )
3276 throw container::NoSuchElementException();
3278 uno::Any aAny;
3280 uno::Reference< beans::XPropertySet > xProps( pPage->getUnoPage(), uno::UNO_QUERY );
3281 if( xProps.is() )
3282 aAny <<= xProps;
3284 return aAny;
3287 uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getElementNames()
3289 ::SolarMutexGuard aGuard;
3291 if( nullptr == mpModel )
3292 throw lang::DisposedException();
3294 SdDrawDocument* pDoc = mpModel->GetDoc();
3295 if( pDoc == nullptr )
3297 return { };
3300 if( pDoc->GetDocumentType() == DocumentType::Draw )
3302 const sal_uInt16 nMaxPages = pDoc->GetSdPageCount( PageKind::Standard );
3303 const sal_uInt16 nMaxMasterPages = pDoc->GetMasterSdPageCount( PageKind::Standard );
3305 uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages );
3306 OUString* pStr = aSeq.getArray();
3308 sal_uInt16 nPage;
3309 // standard pages
3310 for( nPage = 0; nPage < nMaxPages; nPage++ )
3311 *pStr++ = pDoc->GetSdPage( nPage, PageKind::Standard )->GetName();
3313 // master pages
3314 for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3315 *pStr++ = pDoc->GetMasterSdPage( nPage, PageKind::Standard )->GetName();
3316 return aSeq;
3318 else
3320 const sal_uInt16 nMaxPages = pDoc->GetPageCount();
3321 const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
3323 uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages );
3324 OUString* pStr = aSeq.getArray();
3326 sal_uInt16 nPage;
3327 // standard pages
3328 for( nPage = 0; nPage < nMaxPages; nPage++ )
3329 *pStr++ = static_cast<SdPage*>(pDoc->GetPage( nPage ))->GetName();
3331 // master pages
3332 for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3333 *pStr++ = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ))->GetName();
3334 return aSeq;
3338 sal_Bool SAL_CALL SdDocLinkTargets::hasByName( const OUString& aName )
3340 ::SolarMutexGuard aGuard;
3342 if( nullptr == mpModel )
3343 throw lang::DisposedException();
3345 return FindPage( aName ) != nullptr;
3348 // container::XElementAccess
3349 uno::Type SAL_CALL SdDocLinkTargets::getElementType()
3351 return cppu::UnoType<beans::XPropertySet>::get();
3354 sal_Bool SAL_CALL SdDocLinkTargets::hasElements()
3356 ::SolarMutexGuard aGuard;
3358 if( nullptr == mpModel )
3359 throw lang::DisposedException();
3361 return mpModel->GetDoc() != nullptr;
3364 SdPage* SdDocLinkTargets::FindPage( const OUString& rName ) const
3366 SdDrawDocument* pDoc = mpModel->GetDoc();
3367 if( pDoc == nullptr )
3368 return nullptr;
3370 const sal_uInt16 nMaxPages = pDoc->GetPageCount();
3371 const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
3373 sal_uInt16 nPage;
3374 SdPage* pPage;
3376 const bool bDraw = pDoc->GetDocumentType() == DocumentType::Draw;
3378 // standard pages
3379 for( nPage = 0; nPage < nMaxPages; nPage++ )
3381 pPage = static_cast<SdPage*>(pDoc->GetPage( nPage ));
3382 if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
3383 return pPage;
3386 // master pages
3387 for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3389 pPage = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ));
3390 if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
3391 return pPage;
3394 return nullptr;
3397 // XServiceInfo
3398 OUString SAL_CALL SdDocLinkTargets::getImplementationName()
3400 return "SdDocLinkTargets";
3403 sal_Bool SAL_CALL SdDocLinkTargets::supportsService( const OUString& ServiceName )
3405 return cppu::supportsService( this, ServiceName );
3408 uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getSupportedServiceNames()
3410 return { "com.sun.star.document.LinkTargets" };
3413 rtl::Reference< SdXImpressDocument > SdXImpressDocument::GetModel( SdDrawDocument const & rDocument )
3415 rtl::Reference< SdXImpressDocument > xRet;
3416 ::sd::DrawDocShell* pDocShell(rDocument.GetDocSh());
3417 if( pDocShell )
3419 uno::Reference<frame::XModel> xModel(pDocShell->GetModel());
3421 xRet.set( dynamic_cast< SdXImpressDocument* >( xModel.get() ) );
3424 return xRet;
3427 void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName )
3429 rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) );
3431 if( xModel.is() )
3433 uno::Reference< uno::XInterface > xSource( static_cast<uno::XWeak*>( xModel.get() ) );
3434 css::document::EventObject aEvent( xSource, rEventName );
3435 xModel->notifyEvent(aEvent );
3439 void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName, const uno::Reference< uno::XInterface >& xSource )
3441 rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) );
3443 if( xModel.is() )
3445 css::document::EventObject aEvent( xSource, rEventName );
3446 xModel->notifyEvent(aEvent );
3450 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */