Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sd / source / ui / unoidl / unomodel.cxx
blobe05aee0f91c0acc5d1d89cbde864201d236b5eb8
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>
22 #include <com/sun/star/presentation/XPresentation2.hpp>
24 #include <com/sun/star/lang/DisposedException.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
26 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
27 #include <com/sun/star/lang/Locale.hpp>
28 #include <com/sun/star/awt/XDevice.hpp>
29 #include <com/sun/star/document/IndexedPropertyValues.hpp>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
31 #include <com/sun/star/util/XTheme.hpp>
33 #include <com/sun/star/embed/Aspects.hpp>
35 #include <officecfg/Office/Common.hxx>
36 #include <comphelper/indexedpropertyvalues.hxx>
37 #include <comphelper/lok.hxx>
38 #include <comphelper/propertyvalue.hxx>
39 #include <comphelper/sequence.hxx>
40 #include <comphelper/servicehelper.hxx>
41 #include <cppuhelper/supportsservice.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/profilezone.hxx>
45 #include <sal/log.hxx>
46 #include <editeng/unofield.hxx>
47 #include <notifydocumentevent.hxx>
48 #include <tpaction.hxx>
49 #include <unomodel.hxx>
50 #include "unopool.hxx"
51 #include <sfx2/lokhelper.hxx>
52 #include <sfx2/dispatch.hxx>
53 #include <vcl/svapp.hxx>
54 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
56 #include <editeng/UnoForbiddenCharsTable.hxx>
57 #include <svx/svdoutl.hxx>
58 #include <o3tl/safeint.hxx>
59 #include <o3tl/string_view.hxx>
60 #include <o3tl/unit_conversion.hxx>
61 #include <svx/UnoNamespaceMap.hxx>
62 #include <svx/svdlayer.hxx>
63 #include <svx/svdsob.hxx>
64 #include <svx/svdundo.hxx>
65 #include <svx/unoapi.hxx>
66 #include <svx/unofill.hxx>
67 #include <svx/sdrpagewindow.hxx>
68 #include <svx/sdrpaintwindow.hxx>
69 #include <editeng/fontitem.hxx>
70 #include <toolkit/awt/vclxdevice.hxx>
71 #include <svx/svdpool.hxx>
72 #include <svx/svdpagv.hxx>
73 #include <svtools/unoimap.hxx>
74 #include <svtools/slidesorterbaropt.hxx>
75 #include <svx/unoshape.hxx>
76 #include <editeng/unonrule.hxx>
77 #include <editeng/eeitem.hxx>
78 #include <unotools/datetime.hxx>
79 #include <xmloff/autolayout.hxx>
81 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
82 #include <svx/xmleohlp.hxx>
83 #include <svx/xmlgrhlp.hxx>
84 #include <DrawDocShell.hxx>
85 #include <ViewShellBase.hxx>
86 #include "UnoDocumentSettings.hxx"
88 #include <Annotation.hxx>
89 #include <drawdoc.hxx>
90 #include <sdmod.hxx>
91 #include <sdresid.hxx>
92 #include <sdpage.hxx>
94 #include <strings.hrc>
95 #include <strings.hxx>
96 #include "unolayer.hxx"
97 #include <unopage.hxx>
98 #include "unocpres.hxx"
99 #include "unoobj.hxx"
100 #include <stlpool.hxx>
101 #include "unopback.hxx"
102 #include <unokywds.hxx>
104 #include <FrameView.hxx>
105 #include <ClientView.hxx>
106 #include <DrawViewShell.hxx>
107 #include <ViewShell.hxx>
108 #include <Window.hxx>
109 #include <optsitem.hxx>
111 #include <vcl/pdfextoutdevdata.hxx>
112 #include <com/sun/star/presentation/AnimationSpeed.hpp>
113 #include <com/sun/star/presentation/ClickAction.hpp>
114 #include <svx/sdr/contact/viewobjectcontact.hxx>
115 #include <svx/sdr/contact/viewcontact.hxx>
116 #include <svx/sdr/contact/displayinfo.hxx>
118 #include <com/sun/star/office/XAnnotation.hpp>
119 #include <com/sun/star/office/XAnnotationAccess.hpp>
120 #include <com/sun/star/office/XAnnotationEnumeration.hpp>
121 #include <com/sun/star/geometry/RealPoint2D.hpp>
122 #include <com/sun/star/util/DateTime.hpp>
124 #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
126 #include <sfx2/lokcomponenthelpers.hxx>
127 #include <sfx2/LokControlHandler.hxx>
128 #include <tools/gen.hxx>
129 #include <tools/debug.hxx>
130 #include <comphelper/diagnose_ex.hxx>
131 #include <tools/json_writer.hxx>
132 #include <tools/UnitConversion.hxx>
133 #include <svx/ColorSets.hxx>
134 #include <docmodel/theme/Theme.hxx>
136 #include <app.hrc>
138 using namespace ::cppu;
139 using namespace ::com::sun::star;
140 using namespace ::sd;
142 TranslateId SdTPAction::GetClickActionSdResId( presentation::ClickAction eCA )
144 switch( eCA )
146 case presentation::ClickAction_NONE: return STR_CLICK_ACTION_NONE;
147 case presentation::ClickAction_PREVPAGE: return STR_CLICK_ACTION_PREVPAGE;
148 case presentation::ClickAction_NEXTPAGE: return STR_CLICK_ACTION_NEXTPAGE;
149 case presentation::ClickAction_FIRSTPAGE: return STR_CLICK_ACTION_FIRSTPAGE;
150 case presentation::ClickAction_LASTPAGE: return STR_CLICK_ACTION_LASTPAGE;
151 case presentation::ClickAction_BOOKMARK: return STR_CLICK_ACTION_BOOKMARK;
152 case presentation::ClickAction_DOCUMENT: return STR_CLICK_ACTION_DOCUMENT;
153 case presentation::ClickAction_PROGRAM: return STR_CLICK_ACTION_PROGRAM;
154 case presentation::ClickAction_MACRO: return STR_CLICK_ACTION_MACRO;
155 case presentation::ClickAction_SOUND: return STR_CLICK_ACTION_SOUND;
156 case presentation::ClickAction_VERB: return STR_CLICK_ACTION_VERB;
157 case presentation::ClickAction_STOPPRESENTATION: return STR_CLICK_ACTION_STOPPRESENTATION;
158 default: OSL_FAIL( "No StringResource for ClickAction available!" );
160 return {};
163 namespace {
165 class SdUnoForbiddenCharsTable : public SvxUnoForbiddenCharsTable,
166 public SfxListener
168 public:
169 explicit SdUnoForbiddenCharsTable(SdrModel* pModel);
170 virtual ~SdUnoForbiddenCharsTable() override;
172 // SfxListener
173 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) noexcept override;
174 protected:
175 virtual void onChange() override;
177 private:
178 SdrModel* mpModel;
183 SdUnoForbiddenCharsTable::SdUnoForbiddenCharsTable( SdrModel* pModel )
184 : SvxUnoForbiddenCharsTable( pModel->GetForbiddenCharsTable() ), mpModel( pModel )
186 StartListening( *pModel );
189 void SdUnoForbiddenCharsTable::onChange()
191 if( mpModel )
193 mpModel->ReformatAllTextObjects();
197 SdUnoForbiddenCharsTable::~SdUnoForbiddenCharsTable()
199 SolarMutexGuard g;
201 if( mpModel )
202 EndListening( *mpModel );
205 void SdUnoForbiddenCharsTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept
207 if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
208 return;
209 const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
210 if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
212 mpModel = nullptr;
216 const sal_uInt16 WID_MODEL_LANGUAGE = 1;
217 const sal_uInt16 WID_MODEL_TABSTOP = 2;
218 const sal_uInt16 WID_MODEL_VISAREA = 3;
219 const sal_uInt16 WID_MODEL_MAPUNIT = 4;
220 const sal_uInt16 WID_MODEL_FORBCHARS = 5;
221 const sal_uInt16 WID_MODEL_CONTFOCUS = 6;
222 const sal_uInt16 WID_MODEL_DSGNMODE = 7;
223 const sal_uInt16 WID_MODEL_BASICLIBS = 8;
224 const sal_uInt16 WID_MODEL_RUNTIMEUID = 9;
225 const sal_uInt16 WID_MODEL_BUILDID = 10;
226 const sal_uInt16 WID_MODEL_HASVALIDSIGNATURES = 11;
227 const sal_uInt16 WID_MODEL_DIALOGLIBS = 12;
228 const sal_uInt16 WID_MODEL_FONTS = 13;
229 const sal_uInt16 WID_MODEL_INTEROPGRABBAG = 14;
230 const sal_uInt16 WID_MODEL_THEME = 15;
232 static const SvxItemPropertySet* ImplGetDrawModelPropertySet()
234 // Attention: the first parameter HAS TO BE sorted!!!
235 const static SfxItemPropertyMapEntry aDrawModelPropertyMap_Impl[] =
237 { u"BuildId", WID_MODEL_BUILDID, ::cppu::UnoType<OUString>::get(), 0, 0},
238 { sUNO_Prop_CharLocale, WID_MODEL_LANGUAGE, ::cppu::UnoType<lang::Locale>::get(), 0, 0},
239 { sUNO_Prop_TabStop, WID_MODEL_TABSTOP, ::cppu::UnoType<sal_Int32>::get(), 0, 0},
240 { sUNO_Prop_VisibleArea, WID_MODEL_VISAREA, ::cppu::UnoType<awt::Rectangle>::get(), 0, 0},
241 { sUNO_Prop_MapUnit, WID_MODEL_MAPUNIT, ::cppu::UnoType<sal_Int16>::get(), beans::PropertyAttribute::READONLY, 0},
242 { sUNO_Prop_ForbiddenCharacters, WID_MODEL_FORBCHARS, cppu::UnoType<i18n::XForbiddenCharacters>::get(), beans::PropertyAttribute::READONLY, 0},
243 { sUNO_Prop_AutomContFocus, WID_MODEL_CONTFOCUS, cppu::UnoType<bool>::get(), 0, 0},
244 { sUNO_Prop_ApplyFrmDsgnMode, WID_MODEL_DSGNMODE, cppu::UnoType<bool>::get(), 0, 0},
245 { u"BasicLibraries", WID_MODEL_BASICLIBS, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0},
246 { u"DialogLibraries", WID_MODEL_DIALOGLIBS, cppu::UnoType<script::XLibraryContainer>::get(), beans::PropertyAttribute::READONLY, 0},
247 { sUNO_Prop_RuntimeUID, WID_MODEL_RUNTIMEUID, ::cppu::UnoType<OUString>::get(), beans::PropertyAttribute::READONLY, 0},
248 { sUNO_Prop_HasValidSignatures, WID_MODEL_HASVALIDSIGNATURES, ::cppu::UnoType<sal_Bool>::get(), beans::PropertyAttribute::READONLY, 0},
249 { u"Fonts", WID_MODEL_FONTS, cppu::UnoType<uno::Sequence<uno::Any>>::get(), beans::PropertyAttribute::READONLY, 0},
250 { sUNO_Prop_InteropGrabBag, WID_MODEL_INTEROPGRABBAG, cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(), 0, 0},
251 { sUNO_Prop_Theme, WID_MODEL_THEME, cppu::UnoType<util::XTheme>::get(), 0, 0},
253 static SvxItemPropertySet aDrawModelPropertySet_Impl( aDrawModelPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
254 return &aDrawModelPropertySet_Impl;
257 // this ctor is used from the DocShell
258 SdXImpressDocument::SdXImpressDocument(::sd::DrawDocShell* pShell, bool bClipBoard)
259 : SfxBaseModel( pShell ),
260 mpDocShell( pShell ),
261 mpDoc( pShell ? pShell->GetDoc() : nullptr ),
262 mbDisposed(false),
263 mbImpressDoc( pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocumentType() == DocumentType::Impress ),
264 mbClipBoard( bClipBoard ),
265 mpPropSet( ImplGetDrawModelPropertySet() ),
266 mbPaintTextEdit( true )
268 if( mpDoc )
270 StartListening( *mpDoc );
272 else
274 OSL_FAIL("DocShell is invalid");
278 SdXImpressDocument::SdXImpressDocument(SdDrawDocument* pDoc, bool bClipBoard)
279 : SfxBaseModel( nullptr ),
280 mpDocShell( nullptr ),
281 mpDoc( pDoc ),
282 mbDisposed(false),
283 mbImpressDoc( pDoc && pDoc->GetDocumentType() == DocumentType::Impress ),
284 mbClipBoard( bClipBoard ),
285 mpPropSet( ImplGetDrawModelPropertySet() ),
286 mbPaintTextEdit( true )
288 if( mpDoc )
290 StartListening( *mpDoc );
292 else
294 OSL_FAIL("SdDrawDocument is invalid");
298 /***********************************************************************
300 ***********************************************************************/
301 SdXImpressDocument::~SdXImpressDocument() noexcept
305 // XInterface
306 uno::Any SAL_CALL SdXImpressDocument::queryInterface( const uno::Type & rType )
308 uno::Any aAny;
310 if (rType == cppu::UnoType<lang::XServiceInfo>::get())
311 aAny <<= uno::Reference<lang::XServiceInfo>(this);
312 else if (rType == cppu::UnoType<beans::XPropertySet>::get())
313 aAny <<= uno::Reference<beans::XPropertySet>(this);
314 else if (rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
315 aAny <<= uno::Reference<lang::XMultiServiceFactory>(this);
316 else if (rType == cppu::UnoType<drawing::XDrawPageDuplicator>::get())
317 aAny <<= uno::Reference<drawing::XDrawPageDuplicator>(this);
318 else if (rType == cppu::UnoType<drawing::XLayerSupplier>::get())
319 aAny <<= uno::Reference<drawing::XLayerSupplier>(this);
320 else if (rType == cppu::UnoType<drawing::XMasterPagesSupplier>::get())
321 aAny <<= uno::Reference<drawing::XMasterPagesSupplier>(this);
322 else if (rType == cppu::UnoType<drawing::XDrawPagesSupplier>::get())
323 aAny <<= uno::Reference<drawing::XDrawPagesSupplier>(this);
324 else if (rType == cppu::UnoType<presentation::XHandoutMasterSupplier>::get())
325 aAny <<= uno::Reference<presentation::XHandoutMasterSupplier>(this);
326 else if (rType == cppu::UnoType<document::XLinkTargetSupplier>::get())
327 aAny <<= uno::Reference<document::XLinkTargetSupplier>(this);
328 else if (rType == cppu::UnoType<style::XStyleFamiliesSupplier>::get())
329 aAny <<= uno::Reference<style::XStyleFamiliesSupplier>(this);
330 else if (rType == cppu::UnoType<css::ucb::XAnyCompareFactory>::get())
331 aAny <<= uno::Reference<css::ucb::XAnyCompareFactory>(this);
332 else if (rType == cppu::UnoType<view::XRenderable>::get())
333 aAny <<= uno::Reference<view::XRenderable>(this);
334 else if (mbImpressDoc && rType == cppu::UnoType<presentation::XPresentationSupplier>::get())
335 aAny <<= uno::Reference< presentation::XPresentationSupplier >(this);
336 else if (mbImpressDoc && rType == cppu::UnoType<presentation::XCustomPresentationSupplier>::get())
337 aAny <<= uno::Reference< presentation::XCustomPresentationSupplier >(this);
338 else
339 return SfxBaseModel::queryInterface(rType);
341 return aAny;
344 void SAL_CALL SdXImpressDocument::acquire() noexcept
346 SfxBaseModel::acquire();
349 void SAL_CALL SdXImpressDocument::release() noexcept
351 if (osl_atomic_decrement( &m_refCount ) != 0)
352 return;
354 // restore reference count:
355 osl_atomic_increment( &m_refCount );
356 if(!mbDisposed)
360 dispose();
362 catch (const uno::RuntimeException&)
364 // don't break throw ()
365 TOOLS_WARN_EXCEPTION( "sd", "" );
368 SfxBaseModel::release();
371 // XUnoTunnel
372 const css::uno::Sequence< sal_Int8 > & SdXImpressDocument::getUnoTunnelId() noexcept
374 static const comphelper::UnoIdInit theSdXImpressDocumentUnoTunnelId;
375 return theSdXImpressDocumentUnoTunnelId.getSeq();
378 sal_Int64 SAL_CALL SdXImpressDocument::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier )
380 if (comphelper::isUnoTunnelId<SdrModel>(rIdentifier))
381 return comphelper::getSomething_cast(mpDoc);
383 return comphelper::getSomethingImpl(rIdentifier, this,
384 comphelper::FallbackToGetSomethingOf<SfxBaseModel>{});
387 // XTypeProvider
388 uno::Sequence< uno::Type > SAL_CALL SdXImpressDocument::getTypes( )
390 ::SolarMutexGuard aGuard;
392 if( !maTypeSequence.hasElements() )
394 uno::Sequence< uno::Type > aTypes( SfxBaseModel::getTypes() );
395 aTypes = comphelper::concatSequences(aTypes,
396 uno::Sequence {
397 cppu::UnoType<beans::XPropertySet>::get(),
398 cppu::UnoType<lang::XServiceInfo>::get(),
399 cppu::UnoType<lang::XMultiServiceFactory>::get(),
400 cppu::UnoType<drawing::XDrawPageDuplicator>::get(),
401 cppu::UnoType<drawing::XLayerSupplier>::get(),
402 cppu::UnoType<drawing::XMasterPagesSupplier>::get(),
403 cppu::UnoType<drawing::XDrawPagesSupplier>::get(),
404 cppu::UnoType<document::XLinkTargetSupplier>::get(),
405 cppu::UnoType<style::XStyleFamiliesSupplier>::get(),
406 cppu::UnoType<css::ucb::XAnyCompareFactory>::get(),
407 cppu::UnoType<view::XRenderable>::get() });
408 if( mbImpressDoc )
410 aTypes = comphelper::concatSequences(aTypes,
411 uno::Sequence {
412 cppu::UnoType<presentation::XPresentationSupplier>::get(),
413 cppu::UnoType<presentation::XCustomPresentationSupplier>::get(),
414 cppu::UnoType<presentation::XHandoutMasterSupplier>::get() });
416 maTypeSequence = aTypes;
419 return maTypeSequence;
422 uno::Sequence< sal_Int8 > SAL_CALL SdXImpressDocument::getImplementationId( )
424 return css::uno::Sequence<sal_Int8>();
427 /***********************************************************************
429 ***********************************************************************/
430 void SdXImpressDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
432 if( mpDoc )
434 if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
436 const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
437 if( hasEventListeners() )
439 document::EventObject aEvent;
440 if( SvxUnoDrawMSFactory::createEvent( mpDoc, pSdrHint, aEvent ) )
441 notifyEvent( aEvent );
444 if( pSdrHint->GetKind() == SdrHintKind::ModelCleared )
446 if( mpDoc )
447 EndListening( *mpDoc );
448 mpDoc = nullptr;
449 mpDocShell = nullptr;
452 else
454 // did our SdDrawDocument just died?
455 if(rHint.GetId() == SfxHintId::Dying)
457 // yes, so we ask for a new one
458 if( mpDocShell )
460 SdDrawDocument *pNewDoc = mpDocShell->GetDoc();
462 // is there a new one?
463 if( pNewDoc != mpDoc )
465 mpDoc = pNewDoc;
466 if(mpDoc)
467 StartListening( *mpDoc );
473 SfxBaseModel::Notify( rBC, rHint );
476 /******************************************************************************
478 ******************************************************************************/
479 SdPage* SdXImpressDocument::InsertSdPage( sal_uInt16 nPage, bool bDuplicate )
481 sal_uInt16 nPageCount = mpDoc->GetSdPageCount( PageKind::Standard );
482 SdrLayerAdmin& rLayerAdmin = mpDoc->GetLayerAdmin();
483 SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
484 SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
486 rtl::Reference<SdPage> pStandardPage;
488 if( 0 == nPageCount )
490 // this is only used for clipboard where we only have one page
491 pStandardPage = mpDoc->AllocSdPage(false);
493 Size aDefSize(21000, 29700); // A4 portrait orientation
494 pStandardPage->SetSize( aDefSize );
495 mpDoc->InsertPage(pStandardPage.get(), 0);
497 else
499 // here we determine the page after which we should insert
500 SdPage* pPreviousStandardPage = mpDoc->GetSdPage( std::min( static_cast<sal_uInt16>(nPageCount - 1), nPage ), PageKind::Standard );
501 SdrLayerIDSet aVisibleLayers = pPreviousStandardPage->TRG_GetMasterPageVisibleLayers();
502 bool bIsPageBack = aVisibleLayers.IsSet( aBckgrnd );
503 bool bIsPageObj = aVisibleLayers.IsSet( aBckgrndObj );
505 // AutoLayouts must be ready
506 mpDoc->StopWorkStartupDelay();
508 /* First we create a standard page and then a notes page. It is
509 guaranteed, that after a standard page the corresponding notes page
510 follows. */
512 sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
513 SdPage* pPreviousNotesPage = static_cast<SdPage*>( mpDoc->GetPage( nStandardPageNum - 1 ) );
514 sal_uInt16 nNotesPageNum = nStandardPageNum + 1;
516 /**************************************************************
517 * standard page
518 **************************************************************/
519 if( bDuplicate )
520 pStandardPage = static_cast<SdPage*>( pPreviousStandardPage->CloneSdrPage(*mpDoc).get() );
521 else
522 pStandardPage = mpDoc->AllocSdPage(false);
524 pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
525 pStandardPage->SetBorder( pPreviousStandardPage->GetLeftBorder(),
526 pPreviousStandardPage->GetUpperBorder(),
527 pPreviousStandardPage->GetRightBorder(),
528 pPreviousStandardPage->GetLowerBorder() );
529 pStandardPage->SetOrientation( pPreviousStandardPage->GetOrientation() );
530 pStandardPage->SetName(OUString());
532 // insert page after current page
533 mpDoc->InsertPage(pStandardPage.get(), nStandardPageNum);
535 if( !bDuplicate )
537 // use MasterPage of the current page
538 pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
539 pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
540 pStandardPage->SetAutoLayout(AUTOLAYOUT_NONE, true );
543 aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
544 aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
545 aVisibleLayers.Set(aBckgrnd, bIsPageBack);
546 aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
547 pStandardPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
549 /**************************************************************
550 * notes page
551 **************************************************************/
552 rtl::Reference<SdPage> pNotesPage;
554 if( bDuplicate )
555 pNotesPage = static_cast<SdPage*>( pPreviousNotesPage->CloneSdrPage(*mpDoc).get() );
556 else
557 pNotesPage = mpDoc->AllocSdPage(false);
559 pNotesPage->SetSize( pPreviousNotesPage->GetSize() );
560 pNotesPage->SetBorder( pPreviousNotesPage->GetLeftBorder(),
561 pPreviousNotesPage->GetUpperBorder(),
562 pPreviousNotesPage->GetRightBorder(),
563 pPreviousNotesPage->GetLowerBorder() );
564 pNotesPage->SetOrientation( pPreviousNotesPage->GetOrientation() );
565 pNotesPage->SetName(OUString());
566 pNotesPage->SetPageKind(PageKind::Notes);
568 // insert page after current page
569 mpDoc->InsertPage(pNotesPage.get(), nNotesPageNum);
571 if( !bDuplicate )
573 // use MasterPage of the current page
574 pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
575 pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
576 pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true );
580 SetModified();
582 return pStandardPage.get();
585 void SdXImpressDocument::SetModified() noexcept
587 if( mpDoc )
588 mpDoc->SetChanged();
591 // XModel
592 void SAL_CALL SdXImpressDocument::lockControllers( )
594 ::SolarMutexGuard aGuard;
596 if( nullptr == mpDoc )
597 throw lang::DisposedException();
599 mpDoc->setLock(true);
602 void SAL_CALL SdXImpressDocument::unlockControllers( )
604 ::SolarMutexGuard aGuard;
606 if( nullptr == mpDoc )
607 throw lang::DisposedException();
609 if( mpDoc->isLocked() )
611 mpDoc->setLock(false);
615 sal_Bool SAL_CALL SdXImpressDocument::hasControllersLocked( )
617 ::SolarMutexGuard aGuard;
619 if( nullptr == mpDoc )
620 throw lang::DisposedException();
622 return mpDoc->isLocked();
625 uno::Reference < container::XIndexAccess > SAL_CALL SdXImpressDocument::getViewData()
627 ::SolarMutexGuard aGuard;
629 if( nullptr == mpDoc )
630 throw lang::DisposedException();
632 uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
634 if( !xRet.is() )
636 const std::vector<std::unique_ptr<sd::FrameView>> &rList = mpDoc->GetFrameViewList();
638 if( !rList.empty() )
640 xRet = new comphelper::IndexedPropertyValuesContainer();
642 uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
643 DBG_ASSERT( xCont.is(), "SdXImpressDocument::getViewData() failed for OLE object" );
644 if( xCont.is() )
646 for( sal_uInt32 i = 0, n = rList.size(); i < n; i++ )
648 ::sd::FrameView* pFrameView = rList[ i ].get();
650 uno::Sequence< beans::PropertyValue > aSeq;
651 pFrameView->WriteUserDataSequence( aSeq );
652 xCont->insertByIndex( i, uno::Any( aSeq ) );
658 return xRet;
661 void SAL_CALL SdXImpressDocument::setViewData( const uno::Reference < container::XIndexAccess >& xData )
663 ::SolarMutexGuard aGuard;
665 if( nullptr == mpDoc )
666 throw lang::DisposedException();
668 SfxBaseModel::setViewData( xData );
669 if( !(mpDocShell && (mpDocShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) && xData.is()) )
670 return;
672 const sal_Int32 nCount = xData->getCount();
674 std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
676 rViews.clear();
678 uno::Sequence< beans::PropertyValue > aSeq;
679 for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
681 if( xData->getByIndex( nIndex ) >>= aSeq )
683 std::unique_ptr<::sd::FrameView> pFrameView(new ::sd::FrameView( mpDoc ));
684 pFrameView->ReadUserDataSequence( aSeq );
685 rViews.push_back( std::move(pFrameView) );
690 // XDrawPageDuplicator
691 uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::duplicate( const uno::Reference< drawing::XDrawPage >& xPage )
693 ::SolarMutexGuard aGuard;
695 if( nullptr == mpDoc )
696 throw lang::DisposedException();
698 // get pPage from xPage and determine the Id (nPos ) afterwards
699 SvxDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SvxDrawPage>( xPage );
700 if( pSvxPage )
702 SdPage* pPage = static_cast<SdPage*>( pSvxPage->GetSdrPage() );
703 sal_uInt16 nPos = pPage->GetPageNum();
704 nPos = ( nPos - 1 ) / 2;
705 pPage = InsertSdPage( nPos, true );
706 if( pPage )
708 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
709 return xDrawPage;
713 uno::Reference< drawing::XDrawPage > xDrawPage;
714 return xDrawPage;
717 // XDrawPagesSupplier
718 uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getDrawPages()
720 ::SolarMutexGuard aGuard;
722 if( nullptr == mpDoc )
723 throw lang::DisposedException();
725 uno::Reference< drawing::XDrawPages > xDrawPages( mxDrawPagesAccess );
727 if( !xDrawPages.is() )
729 initializeDocument();
730 mxDrawPagesAccess = xDrawPages = new SdDrawPagesAccess(*this);
733 return xDrawPages;
736 // XMasterPagesSupplier
737 uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getMasterPages()
739 ::SolarMutexGuard aGuard;
741 if( nullptr == mpDoc )
742 throw lang::DisposedException();
744 uno::Reference< drawing::XDrawPages > xMasterPages( mxMasterPagesAccess );
746 if( !xMasterPages.is() )
748 if ( !hasControllersLocked() )
749 initializeDocument();
750 mxMasterPagesAccess = xMasterPages = new SdMasterPagesAccess(*this);
753 return xMasterPages;
756 // XLayerManagerSupplier
757 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLayerManager( )
759 ::SolarMutexGuard aGuard;
761 if( nullptr == mpDoc )
762 throw lang::DisposedException();
764 uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager );
766 if( !xLayerManager.is() )
767 mxLayerManager = xLayerManager = new SdLayerManager(*this);
769 return xLayerManager;
772 // XCustomPresentationSupplier
773 uno::Reference< container::XNameContainer > SAL_CALL SdXImpressDocument::getCustomPresentations()
775 ::SolarMutexGuard aGuard;
777 if( nullptr == mpDoc )
778 throw lang::DisposedException();
780 uno::Reference< container::XNameContainer > xCustomPres( mxCustomPresentationAccess );
782 if( !xCustomPres.is() )
783 mxCustomPresentationAccess = xCustomPres = new SdXCustomPresentationAccess(*this);
785 return xCustomPres;
788 // XPresentationSupplier
789 uno::Reference< presentation::XPresentation > SAL_CALL SdXImpressDocument::getPresentation()
791 ::SolarMutexGuard aGuard;
793 if( nullptr == mpDoc )
794 throw lang::DisposedException();
796 return mpDoc->getPresentation();
799 // XHandoutMasterSupplier
800 uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::getHandoutMasterPage()
802 ::SolarMutexGuard aGuard;
804 if( nullptr == mpDoc )
805 throw lang::DisposedException();
807 uno::Reference< drawing::XDrawPage > xPage;
809 initializeDocument();
810 SdPage* pPage = mpDoc->GetMasterSdPage(0, PageKind::Handout);
811 if (pPage)
812 xPage.set(pPage->getUnoPage(), uno::UNO_QUERY);
813 return xPage;
816 // XMultiServiceFactory ( SvxFmMSFactory )
818 css::uno::Reference<css::uno::XInterface> SdXImpressDocument::create(
819 OUString const & aServiceSpecifier, OUString const & referer)
821 ::SolarMutexGuard aGuard;
823 if( nullptr == mpDoc )
824 throw lang::DisposedException();
826 if( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
828 if( !mxDashTable.is() )
829 mxDashTable = SvxUnoDashTable_createInstance( mpDoc );
831 return mxDashTable;
833 if( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
835 if( !mxGradientTable.is() )
836 mxGradientTable = SvxUnoGradientTable_createInstance( mpDoc );
838 return mxGradientTable;
840 if( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
842 if( !mxHatchTable.is() )
843 mxHatchTable = SvxUnoHatchTable_createInstance( mpDoc );
845 return mxHatchTable;
847 if( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
849 if( !mxBitmapTable.is() )
850 mxBitmapTable = SvxUnoBitmapTable_createInstance( mpDoc );
852 return mxBitmapTable;
854 if( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
856 if( !mxTransGradientTable.is() )
857 mxTransGradientTable = SvxUnoTransGradientTable_createInstance( mpDoc );
859 return mxTransGradientTable;
861 if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
863 if( !mxMarkerTable.is() )
864 mxMarkerTable = SvxUnoMarkerTable_createInstance( mpDoc );
866 return mxMarkerTable;
868 if( aServiceSpecifier == "com.sun.star.text.NumberingRules" )
870 return uno::Reference< uno::XInterface >( SvxCreateNumRule( mpDoc ), uno::UNO_QUERY );
872 if( aServiceSpecifier == "com.sun.star.drawing.Background" )
874 return uno::Reference< uno::XInterface >(
875 static_cast<uno::XWeak*>(new SdUnoPageBackground( mpDoc )));
878 if( aServiceSpecifier == "com.sun.star.drawing.Defaults" )
880 if( !mxDrawingPool.is() )
881 mxDrawingPool = SdUnoCreatePool( mpDoc );
883 return mxDrawingPool;
887 if ( aServiceSpecifier == sUNO_Service_ImageMapRectangleObject )
889 return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
892 if ( aServiceSpecifier == sUNO_Service_ImageMapCircleObject )
894 return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
897 if ( aServiceSpecifier == sUNO_Service_ImageMapPolygonObject )
899 return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
902 if( aServiceSpecifier == "com.sun.star.document.Settings" ||
903 ( !mbImpressDoc && ( aServiceSpecifier == "com.sun.star.drawing.DocumentSettings" ) ) ||
904 ( mbImpressDoc && ( aServiceSpecifier == "com.sun.star.presentation.DocumentSettings" ) ) )
906 return sd::DocumentSettings_createInstance( this );
909 if( aServiceSpecifier == "com.sun.star.text.TextField.DateTime" ||
910 aServiceSpecifier == "com.sun.star.text.textfield.DateTime" )
912 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::DATE ));
915 if( aServiceSpecifier == "com.sun.star.presentation.TextField.Header" ||
916 aServiceSpecifier == "com.sun.star.presentation.textfield.Header" )
918 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_HEADER ));
921 if( aServiceSpecifier == "com.sun.star.presentation.TextField.Footer" ||
922 aServiceSpecifier == "com.sun.star.presentation.textfield.Footer" )
924 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_FOOTER ));
927 if( aServiceSpecifier == "com.sun.star.presentation.TextField.DateTime" ||
928 aServiceSpecifier == "com.sun.star.presentation.textfield.DateTime" )
930 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_DATE_TIME ));
933 if( aServiceSpecifier == "com.sun.star.text.TextField.PageName" ||
934 aServiceSpecifier == "com.sun.star.text.textfield.PageName" )
936 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PAGE_NAME ));
939 if (aServiceSpecifier == "com.sun.star.text.TextField.DocInfo.Custom" ||
940 aServiceSpecifier == "com.sun.star.text.textfield.DocInfo.Custom")
942 return static_cast<cppu::OWeakObject *>(new SvxUnoTextField(text::textfield::Type::DOCINFO_CUSTOM));
945 if( aServiceSpecifier == "com.sun.star.xml.NamespaceMap" )
947 static sal_uInt16 aWhichIds[] = { SDRATTR_XMLATTRIBUTES, EE_CHAR_XMLATTRIBS, EE_PARA_XMLATTRIBS, 0 };
949 return svx::NamespaceMap_createInstance( aWhichIds, &mpDoc->GetItemPool() );
952 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
953 if (aServiceSpecifier == "com.sun.star.document.ExportGraphicStorageHandler")
955 return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Write ));
958 if (aServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler")
960 return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Read ));
963 if( aServiceSpecifier == "com.sun.star.document.ExportEmbeddedObjectResolver" )
965 comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
966 if( nullptr == pPersist )
967 throw lang::DisposedException();
969 return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Write ));
972 if( aServiceSpecifier == "com.sun.star.document.ImportEmbeddedObjectResolver" )
974 comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
975 if( nullptr == pPersist )
976 throw lang::DisposedException();
978 return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Read ));
981 uno::Reference< uno::XInterface > xRet;
983 if( aServiceSpecifier.startsWith( "com.sun.star.presentation.") )
985 const std::u16string_view aType( aServiceSpecifier.subView(26) );
986 rtl::Reference<SvxShape> pShape;
988 SdrObjKind nType = SdrObjKind::Text;
989 // create a shape wrapper
990 if( o3tl::starts_with(aType, u"TitleTextShape" ) )
992 nType = SdrObjKind::Text;
994 else if( o3tl::starts_with(aType, u"OutlinerShape" ) )
996 nType = SdrObjKind::Text;
998 else if( o3tl::starts_with(aType, u"SubtitleShape" ) )
1000 nType = SdrObjKind::Text;
1002 else if( o3tl::starts_with(aType, u"GraphicObjectShape" ) )
1004 nType = SdrObjKind::Graphic;
1006 else if( o3tl::starts_with(aType, u"PageShape" ) )
1008 nType = SdrObjKind::Page;
1010 else if( o3tl::starts_with(aType, u"OLE2Shape" ) )
1012 nType = SdrObjKind::OLE2;
1014 else if( o3tl::starts_with(aType, u"ChartShape" ) )
1016 nType = SdrObjKind::OLE2;
1018 else if( o3tl::starts_with(aType, u"CalcShape" ) )
1020 nType = SdrObjKind::OLE2;
1022 else if( o3tl::starts_with(aType, u"TableShape" ) )
1024 nType = SdrObjKind::Table;
1026 else if( o3tl::starts_with(aType, u"OrgChartShape" ) )
1028 nType = SdrObjKind::OLE2;
1030 else if( o3tl::starts_with(aType, u"NotesShape" ) )
1032 nType = SdrObjKind::Text;
1034 else if( o3tl::starts_with(aType, u"HandoutShape" ) )
1036 nType = SdrObjKind::Page;
1038 else if( o3tl::starts_with(aType, u"FooterShape" ) )
1040 nType = SdrObjKind::Text;
1042 else if( o3tl::starts_with(aType, u"HeaderShape" ) )
1044 nType = SdrObjKind::Text;
1046 else if( o3tl::starts_with(aType, u"SlideNumberShape" ) )
1048 nType = SdrObjKind::Text;
1050 else if( o3tl::starts_with(aType, u"DateTimeShape" ) )
1052 nType = SdrObjKind::Text;
1054 else if( o3tl::starts_with(aType, u"MediaShape" ) )
1056 nType = SdrObjKind::Media;
1058 else
1060 throw lang::ServiceNotRegisteredException();
1063 // create the API wrapper
1064 pShape = CreateSvxShapeByTypeAndInventor( nType, SdrInventor::Default, referer );
1066 // set shape type
1067 if( pShape && !mbClipBoard )
1068 pShape->SetShapeType(aServiceSpecifier);
1070 xRet = static_cast<uno::XWeak*>(pShape.get());
1072 else if ( aServiceSpecifier == "com.sun.star.drawing.TableShape" )
1074 rtl::Reference<SvxShape> pShape = CreateSvxShapeByTypeAndInventor( SdrObjKind::Table, SdrInventor::Default, referer );
1075 if( pShape && !mbClipBoard )
1076 pShape->SetShapeType(aServiceSpecifier);
1078 xRet = static_cast<uno::XWeak*>(pShape.get());
1080 else
1082 xRet = SvxFmMSFactory::createInstance( aServiceSpecifier );
1085 uno::Reference< drawing::XShape > xShape( xRet, uno::UNO_QUERY );
1086 SvxShape* pShape = xShape.is() ? comphelper::getFromUnoTunnel<SvxShape>(xShape) : nullptr;
1087 if (pShape)
1089 xRet.clear();
1090 new SdXShape( pShape, this );
1091 xRet = xShape;
1092 xShape.clear();
1095 return xRet;
1098 uno::Reference< uno::XInterface > SAL_CALL SdXImpressDocument::createInstance( const OUString& aServiceSpecifier )
1100 return create(aServiceSpecifier, "");
1103 css::uno::Reference<css::uno::XInterface>
1104 SdXImpressDocument::createInstanceWithArguments(
1105 OUString const & ServiceSpecifier,
1106 css::uno::Sequence<css::uno::Any> const & Arguments)
1108 OUString arg;
1109 if ((ServiceSpecifier == "com.sun.star.drawing.GraphicObjectShape"
1110 || ServiceSpecifier == "com.sun.star.drawing.MediaShape"
1111 || ServiceSpecifier == "com.sun.star.presentation.MediaShape")
1112 && Arguments.getLength() == 1 && (Arguments[0] >>= arg))
1114 return create(ServiceSpecifier, arg);
1116 return SvxFmMSFactory::createInstanceWithArguments(
1117 ServiceSpecifier, Arguments);
1120 uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getAvailableServiceNames()
1122 ::SolarMutexGuard aGuard;
1124 if( nullptr == mpDoc )
1125 throw lang::DisposedException();
1127 const uno::Sequence< OUString > aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
1129 uno::Sequence< OUString > aSNS_Common{ "com.sun.star.drawing.DashTable",
1130 "com.sun.star.drawing.GradientTable",
1131 "com.sun.star.drawing.HatchTable",
1132 "com.sun.star.drawing.BitmapTable",
1133 "com.sun.star.drawing.TransparencyGradientTable",
1134 "com.sun.star.drawing.MarkerTable",
1135 "com.sun.star.text.NumberingRules",
1136 "com.sun.star.drawing.Background",
1137 "com.sun.star.document.Settings",
1138 sUNO_Service_ImageMapRectangleObject,
1139 sUNO_Service_ImageMapCircleObject,
1140 sUNO_Service_ImageMapPolygonObject,
1141 "com.sun.star.xml.NamespaceMap",
1143 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
1144 "com.sun.star.document.ExportGraphicStorageHandler",
1145 "com.sun.star.document.ImportGraphicStorageHandler",
1146 "com.sun.star.document.ExportEmbeddedObjectResolver",
1147 "com.sun.star.document.ImportEmbeddedObjectResolver",
1148 "com.sun.star.drawing.TableShape" };
1150 uno::Sequence< OUString > aSNS_Specific;
1152 if(mbImpressDoc)
1153 aSNS_Specific = { "com.sun.star.presentation.TitleTextShape",
1154 "com.sun.star.presentation.OutlinerShape",
1155 "com.sun.star.presentation.SubtitleShape",
1156 "com.sun.star.presentation.GraphicObjectShape",
1157 "com.sun.star.presentation.ChartShape",
1158 "com.sun.star.presentation.PageShape",
1159 "com.sun.star.presentation.OLE2Shape",
1160 "com.sun.star.presentation.TableShape",
1161 "com.sun.star.presentation.OrgChartShape",
1162 "com.sun.star.presentation.NotesShape",
1163 "com.sun.star.presentation.HandoutShape",
1164 "com.sun.star.presentation.DocumentSettings",
1165 "com.sun.star.presentation.FooterShape",
1166 "com.sun.star.presentation.HeaderShape",
1167 "com.sun.star.presentation.SlideNumberShape",
1168 "com.sun.star.presentation.DateTimeShape",
1169 "com.sun.star.presentation.CalcShape",
1170 "com.sun.star.presentation.MediaShape" };
1171 else
1172 aSNS_Specific = { "com.sun.star.drawing.DocumentSettings" };
1174 return comphelper::concatSequences( aSNS_ORG, aSNS_Common, aSNS_Specific );
1177 // lang::XServiceInfo
1178 OUString SAL_CALL SdXImpressDocument::getImplementationName()
1180 return "SdXImpressDocument";
1181 /* // Matching the .component information:
1182 return mbImpressDoc
1183 ? OUString("com.sun.star.comp.Draw.PresentationDocument")
1184 : OUString("com.sun.star.comp.Draw.DrawingDocument");
1188 sal_Bool SAL_CALL SdXImpressDocument::supportsService( const OUString& ServiceName )
1190 return cppu::supportsService(this, ServiceName);
1193 uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getSupportedServiceNames()
1195 ::SolarMutexGuard aGuard;
1197 return { "com.sun.star.document.OfficeDocument",
1198 "com.sun.star.drawing.GenericDrawingDocument",
1199 "com.sun.star.drawing.DrawingDocumentFactory",
1200 mbImpressDoc?OUString("com.sun.star.presentation.PresentationDocument"):OUString("com.sun.star.drawing.DrawingDocument") };
1203 // XPropertySet
1204 uno::Reference< beans::XPropertySetInfo > SAL_CALL SdXImpressDocument::getPropertySetInfo( )
1206 ::SolarMutexGuard aGuard;
1207 return mpPropSet->getPropertySetInfo();
1210 void SAL_CALL SdXImpressDocument::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
1212 ::SolarMutexGuard aGuard;
1214 if( nullptr == mpDoc )
1215 throw lang::DisposedException();
1217 const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
1219 switch( pEntry ? pEntry->nWID : -1 )
1221 case WID_MODEL_LANGUAGE:
1223 lang::Locale aLocale;
1224 if(!(aValue >>= aLocale))
1225 throw lang::IllegalArgumentException();
1227 mpDoc->SetLanguage( LanguageTag::convertToLanguageType(aLocale), EE_CHAR_LANGUAGE );
1228 break;
1230 case WID_MODEL_TABSTOP:
1232 sal_Int32 nValue = 0;
1233 if(!(aValue >>= nValue) || nValue < 0 )
1234 throw lang::IllegalArgumentException();
1236 mpDoc->SetDefaultTabulator(static_cast<sal_uInt16>(nValue));
1237 break;
1239 case WID_MODEL_VISAREA:
1241 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1242 if( !pEmbeddedObj )
1243 break;
1245 awt::Rectangle aVisArea;
1246 if( !(aValue >>= aVisArea) || (aVisArea.Width < 0) || (aVisArea.Height < 0) )
1247 throw lang::IllegalArgumentException();
1249 sal_Int32 nRight, nTop;
1250 if (o3tl::checked_add(aVisArea.X, aVisArea.Width, nRight) || o3tl::checked_add(aVisArea.Y, aVisArea.Height, nTop))
1251 throw lang::IllegalArgumentException();
1253 pEmbeddedObj->SetVisArea(::tools::Rectangle(aVisArea.X, aVisArea.Y, nRight, nTop));
1255 break;
1256 case WID_MODEL_CONTFOCUS:
1258 bool bFocus = false;
1259 if( !(aValue >>= bFocus ) )
1260 throw lang::IllegalArgumentException();
1261 mpDoc->SetAutoControlFocus( bFocus );
1263 break;
1264 case WID_MODEL_DSGNMODE:
1266 bool bMode = false;
1267 if( !(aValue >>= bMode ) )
1268 throw lang::IllegalArgumentException();
1269 mpDoc->SetOpenInDesignMode( bMode );
1271 break;
1272 case WID_MODEL_BUILDID:
1273 aValue >>= maBuildId;
1274 return;
1275 case WID_MODEL_MAPUNIT:
1276 case WID_MODEL_BASICLIBS:
1277 case WID_MODEL_RUNTIMEUID: // is read-only
1278 case WID_MODEL_DIALOGLIBS:
1279 case WID_MODEL_FONTS:
1280 throw beans::PropertyVetoException();
1281 case WID_MODEL_INTEROPGRABBAG:
1282 setGrabBagItem(aValue);
1283 break;
1284 case WID_MODEL_THEME:
1286 SdrModel& rModel = getSdrModelFromUnoModel();
1287 std::shared_ptr<model::Theme> pTheme = model::Theme::FromAny(aValue);
1288 rModel.setTheme(pTheme);
1290 break;
1291 default:
1292 throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
1295 SetModified();
1298 uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& PropertyName )
1300 ::SolarMutexGuard aGuard;
1302 uno::Any aAny;
1303 if( nullptr == mpDoc )
1304 throw lang::DisposedException();
1306 const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
1308 switch( pEntry ? pEntry->nWID : -1 )
1310 case WID_MODEL_LANGUAGE:
1312 LanguageType eLang = mpDoc->GetLanguage( EE_CHAR_LANGUAGE );
1313 aAny <<= LanguageTag::convertToLocale( eLang);
1314 break;
1316 case WID_MODEL_TABSTOP:
1317 aAny <<= static_cast<sal_Int32>(mpDoc->GetDefaultTabulator());
1318 break;
1319 case WID_MODEL_VISAREA:
1321 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1322 if( !pEmbeddedObj )
1323 break;
1325 const ::tools::Rectangle& aRect = pEmbeddedObj->GetVisArea();
1326 awt::Rectangle aVisArea( aRect.Left(), aRect.Top(), aRect.getOpenWidth(), aRect.getOpenHeight() );
1327 aAny <<= aVisArea;
1329 break;
1330 case WID_MODEL_MAPUNIT:
1332 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1333 if( !pEmbeddedObj )
1334 break;
1336 sal_Int16 nMeasureUnit = 0;
1337 SvxMapUnitToMeasureUnit( pEmbeddedObj->GetMapUnit(), nMeasureUnit );
1338 aAny <<= nMeasureUnit;
1340 break;
1341 case WID_MODEL_FORBCHARS:
1343 aAny <<= getForbiddenCharsTable();
1345 break;
1346 case WID_MODEL_CONTFOCUS:
1347 aAny <<= mpDoc->GetAutoControlFocus();
1348 break;
1349 case WID_MODEL_DSGNMODE:
1350 aAny <<= mpDoc->GetOpenInDesignMode();
1351 break;
1352 case WID_MODEL_BASICLIBS:
1353 aAny <<= mpDocShell->GetBasicContainer();
1354 break;
1355 case WID_MODEL_DIALOGLIBS:
1356 aAny <<= mpDocShell->GetDialogContainer();
1357 break;
1358 case WID_MODEL_RUNTIMEUID:
1359 aAny <<= getRuntimeUID();
1360 break;
1361 case WID_MODEL_BUILDID:
1362 return uno::Any( maBuildId );
1363 case WID_MODEL_HASVALIDSIGNATURES:
1364 aAny <<= hasValidSignatures();
1365 break;
1366 case WID_MODEL_FONTS:
1368 uno::Sequence<uno::Any> aSeq;
1369 int nSeqIndex = 0;
1371 sal_uInt16 const aWhichIds[] { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
1372 EE_CHAR_FONTINFO_CTL };
1374 const SfxItemPool& rPool = mpDoc->GetPool();
1376 for(sal_uInt16 nWhichId : aWhichIds)
1378 sal_uInt32 nItems = rPool.GetItemCount2( nWhichId );
1380 aSeq.realloc( aSeq.getLength() + nItems*5 + 5 );
1381 auto pSeq = aSeq.getArray();
1383 for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId))
1385 const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem);
1387 pSeq[nSeqIndex++] <<= pFont->GetFamilyName();
1388 pSeq[nSeqIndex++] <<= pFont->GetStyleName();
1389 pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily());
1390 pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch());
1391 pSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet());
1394 const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetDefaultItem( nWhichId ));
1396 pSeq[nSeqIndex++] <<= rFont.GetFamilyName();
1397 pSeq[nSeqIndex++] <<= rFont.GetStyleName();
1398 pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetFamily());
1399 pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetPitch());
1400 pSeq[nSeqIndex++] <<= sal_Int16(rFont.GetCharSet());
1404 aSeq.realloc( nSeqIndex );
1405 aAny <<= aSeq;
1406 break;
1408 case WID_MODEL_INTEROPGRABBAG:
1409 getGrabBagItem(aAny);
1410 break;
1411 case WID_MODEL_THEME:
1413 SdrModel& rModel = getSdrModelFromUnoModel();
1414 auto const& pTheme = rModel.getTheme();
1415 if (pTheme)
1417 pTheme->ToAny(aAny);
1419 else
1421 beans::PropertyValues aValues;
1422 aAny <<= aValues;
1424 break;
1426 default:
1427 throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1430 return aAny;
1433 void SAL_CALL SdXImpressDocument::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {}
1434 void SAL_CALL SdXImpressDocument::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >& ) {}
1435 void SAL_CALL SdXImpressDocument::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {}
1436 void SAL_CALL SdXImpressDocument::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >& ) {}
1438 // XLinkTargetSupplier
1439 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLinks()
1441 ::SolarMutexGuard aGuard;
1443 if( nullptr == mpDoc )
1444 throw lang::DisposedException();
1446 uno::Reference< container::XNameAccess > xLinks( mxLinks );
1447 if( !xLinks.is() )
1448 mxLinks = xLinks = new SdDocLinkTargets( *this );
1449 return xLinks;
1452 // XStyleFamiliesSupplier
1453 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getStyleFamilies( )
1455 ::SolarMutexGuard aGuard;
1457 if( nullptr == mpDoc )
1458 throw lang::DisposedException();
1460 uno::Reference< container::XNameAccess > xStyles( static_cast< OWeakObject* >( mpDoc->GetStyleSheetPool() ), css::uno::UNO_QUERY );
1461 return xStyles;
1464 // XAnyCompareFactory
1465 uno::Reference< css::ucb::XAnyCompare > SAL_CALL SdXImpressDocument::createAnyCompareByName( const OUString& )
1467 return SvxCreateNumRuleCompare();
1470 // XRenderable
1471 sal_Int32 SAL_CALL SdXImpressDocument::getRendererCount( const uno::Any& rSelection,
1472 const uno::Sequence< beans::PropertyValue >& )
1474 ::SolarMutexGuard aGuard;
1475 sal_Int32 nRet = 0;
1477 if( nullptr == mpDoc )
1478 throw lang::DisposedException();
1480 if (mpDocShell)
1482 uno::Reference< frame::XModel > xModel;
1484 rSelection >>= xModel;
1486 if( xModel == mpDocShell->GetModel() )
1487 nRet = mpDoc->GetSdPageCount( PageKind::Standard );
1488 else
1490 uno::Reference< drawing::XShapes > xShapes;
1492 rSelection >>= xShapes;
1494 if( xShapes.is() && xShapes->getCount() )
1495 nRet = 1;
1498 return nRet;
1501 uno::Sequence< beans::PropertyValue > SAL_CALL SdXImpressDocument::getRenderer( sal_Int32 , const uno::Any& ,
1502 const uno::Sequence< beans::PropertyValue >& rxOptions )
1504 ::SolarMutexGuard aGuard;
1506 if( nullptr == mpDoc )
1507 throw lang::DisposedException();
1509 bool bExportNotesPages = false;
1510 for( const auto& rOption : rxOptions )
1512 if ( rOption.Name == "ExportNotesPages" )
1513 rOption.Value >>= bExportNotesPages;
1515 uno::Sequence< beans::PropertyValue > aRenderer;
1516 if (mpDocShell)
1518 awt::Size aPageSize;
1519 if ( bExportNotesPages )
1521 Size aNotesPageSize = mpDoc->GetSdPage( 0, PageKind::Notes )->GetSize();
1522 aPageSize = awt::Size( aNotesPageSize.Width(), aNotesPageSize.Height() );
1524 else
1526 const ::tools::Rectangle aVisArea( mpDocShell->GetVisArea( embed::Aspects::MSOLE_DOCPRINT ) );
1527 aPageSize = awt::Size( aVisArea.GetWidth(), aVisArea.GetHeight() );
1529 aRenderer = { comphelper::makePropertyValue("PageSize", aPageSize) };
1531 return aRenderer;
1534 namespace {
1536 class ImplRenderPaintProc : public sdr::contact::ViewObjectContactRedirector
1538 const SdrLayerAdmin& rLayerAdmin;
1539 SdrPageView* pSdrPageView;
1541 public:
1542 bool IsVisible ( const SdrObject* pObj ) const;
1543 bool IsPrintable( const SdrObject* pObj ) const;
1545 ImplRenderPaintProc(const SdrLayerAdmin& rLA, SdrPageView* pView);
1547 // all default implementations just call the same methods at the original. To do something
1548 // different, override the method and at least do what the method does.
1549 virtual void createRedirectedPrimitive2DSequence(
1550 const sdr::contact::ViewObjectContact& rOriginal,
1551 const sdr::contact::DisplayInfo& rDisplayInfo,
1552 drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor) override;
1557 ImplRenderPaintProc::ImplRenderPaintProc(const SdrLayerAdmin& rLA, SdrPageView *const pView)
1558 : rLayerAdmin(rLA)
1559 , pSdrPageView(pView)
1563 static sal_Int32 ImplPDFGetBookmarkPage( const OUString& rBookmark, SdDrawDocument const & rDoc )
1565 sal_Int32 nPage = -1;
1567 OUString aBookmark( rBookmark );
1569 if( rBookmark.startsWith("#") )
1570 aBookmark = rBookmark.copy( 1 );
1572 // is the bookmark a page ?
1573 bool bIsMasterPage;
1574 sal_uInt16 nPgNum = rDoc.GetPageByName( aBookmark, bIsMasterPage );
1576 if ( nPgNum == SDRPAGE_NOTFOUND )
1578 // is the bookmark an object ?
1579 SdrObject* pObj = rDoc.GetObj( aBookmark );
1580 if (pObj)
1581 nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum();
1583 if ( nPgNum != SDRPAGE_NOTFOUND )
1584 nPage = ( nPgNum - 1 ) / 2;
1585 return nPage;
1588 static void ImplPDFExportComments( const uno::Reference< drawing::XDrawPage >& xPage, vcl::PDFExtOutDevData& rPDFExtOutDevData )
1592 uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW );
1593 uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
1595 while( xAnnotationEnumeration->hasMoreElements() )
1597 uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() );
1599 geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() );
1600 geometry::RealSize2D aRealSize2D(xAnnotation->getSize());
1601 uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
1603 vcl::PDFNote aNote;
1604 aNote.Title = xAnnotation->getAuthor();
1605 aNote.Contents = xText->getString();
1606 aNote.maModificationDate = xAnnotation->getDateTime();
1607 auto* pAnnotation = dynamic_cast<sd::Annotation*>(xAnnotation.get());
1608 aNote.isFreeText = pAnnotation && pAnnotation->isFreeText();
1609 if (pAnnotation && pAnnotation->hasCustomAnnotationMarker())
1611 aNote.maPolygons = pAnnotation->getCustomAnnotationMarker().maPolygons;
1612 aNote.annotColor = pAnnotation->getCustomAnnotationMarker().maLineColor;
1613 aNote.interiorColor = pAnnotation->getCustomAnnotationMarker().maFillColor;
1616 rPDFExtOutDevData.CreateNote(
1617 ::tools::Rectangle(Point(static_cast<::tools::Long>(aRealPoint2D.X * 100),
1618 static_cast<::tools::Long>(aRealPoint2D.Y * 100)),
1619 Size(static_cast<::tools::Long>(aRealSize2D.Width * 100),
1620 static_cast<::tools::Long>(aRealSize2D.Height * 100))),
1621 aNote);
1624 catch (const uno::Exception&)
1629 static void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xShape, SdDrawDocument& rDoc, vcl::PDFExtOutDevData& rPDFExtOutDevData )
1631 if ( xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1633 uno::Reference< container::XIndexAccess > xIndexAccess( xShape, uno::UNO_QUERY );
1634 if ( xIndexAccess.is() )
1636 sal_Int32 i, nCount = xIndexAccess->getCount();
1637 for ( i = 0; i < nCount; i++ )
1639 uno::Reference< drawing::XShape > xSubShape( xIndexAccess->getByIndex( i ), uno::UNO_QUERY );
1640 if ( xSubShape.is() )
1641 ImplPDFExportShapeInteraction( xSubShape, rDoc, rPDFExtOutDevData );
1645 else
1647 uno::Reference< beans::XPropertySet > xShapePropSet( xShape, uno::UNO_QUERY );
1648 if( xShapePropSet.is() )
1650 Size aPageSize( rDoc.GetSdPage( 0, PageKind::Standard )->GetSize() );
1651 Point aPoint( 0, 0 );
1652 ::tools::Rectangle aPageRect( aPoint, aPageSize );
1654 awt::Point aShapePos( xShape->getPosition() );
1655 awt::Size aShapeSize( xShape->getSize() );
1656 ::tools::Rectangle aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) );
1658 // Handle linked videos.
1659 if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape")
1661 OUString title;
1662 xShapePropSet->getPropertyValue("Title") >>= title;
1663 OUString description;
1664 xShapePropSet->getPropertyValue("Description") >>= description;
1665 OUString const altText(title.isEmpty()
1666 ? description
1667 : description.isEmpty()
1668 ? title
1669 : OUString::Concat(title) + OUString::Concat("\n") + OUString::Concat(description));
1671 OUString aMediaURL;
1672 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
1673 if (!aMediaURL.isEmpty())
1675 SdrObject const*const pSdrObj(SdrObject::getSdrObjectFromXShape(xShape));
1676 OUString const mimeType(xShapePropSet->getPropertyValue("MediaMimeType").get<OUString>());
1677 sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, altText, mimeType, rPDFExtOutDevData.GetCurrentPageNumber(), pSdrObj);
1678 if (aMediaURL.startsWith("vnd.sun.star.Package:"))
1680 OUString aTempFileURL;
1681 xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
1682 rPDFExtOutDevData.SetScreenStream(nScreenId, aTempFileURL);
1684 else
1685 rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
1689 presentation::ClickAction eCa;
1690 uno::Any aAny( xShapePropSet->getPropertyValue( "OnClick" ) );
1691 if ( aAny >>= eCa )
1693 OUString const actionName(SdResId(SdTPAction::GetClickActionSdResId(eCa)));
1694 switch ( eCa )
1696 case presentation::ClickAction_LASTPAGE :
1698 sal_Int32 nCount = rDoc.GetSdPageCount( PageKind::Standard );
1699 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nCount - 1, vcl::PDFWriter::DestAreaType::FitRectangle );
1700 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
1701 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1703 break;
1704 case presentation::ClickAction_FIRSTPAGE :
1706 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, 0, vcl::PDFWriter::DestAreaType::FitRectangle );
1707 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
1708 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1710 break;
1711 case presentation::ClickAction_PREVPAGE :
1713 sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber();
1714 if ( nDestPage )
1715 nDestPage--;
1716 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1717 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
1718 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1720 break;
1721 case presentation::ClickAction_NEXTPAGE :
1723 sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber() + 1;
1724 sal_Int32 nLastPage = rDoc.GetSdPageCount( PageKind::Standard ) - 1;
1725 if ( nDestPage > nLastPage )
1726 nDestPage = nLastPage;
1727 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1728 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
1729 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1731 break;
1733 case presentation::ClickAction_PROGRAM :
1734 case presentation::ClickAction_BOOKMARK :
1735 case presentation::ClickAction_DOCUMENT :
1737 OUString aBookmark;
1738 xShapePropSet->getPropertyValue( "Bookmark" ) >>= aBookmark;
1739 if( !aBookmark.isEmpty() )
1741 switch( eCa )
1743 case presentation::ClickAction_DOCUMENT :
1744 case presentation::ClickAction_PROGRAM :
1746 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
1747 rPDFExtOutDevData.SetLinkURL( nLinkId, aBookmark );
1749 break;
1750 case presentation::ClickAction_BOOKMARK :
1752 sal_Int32 nPage = ImplPDFGetBookmarkPage( aBookmark, rDoc );
1753 if ( nPage != -1 )
1755 sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1756 sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink(aLinkRect, actionName);
1757 rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1760 break;
1761 default:
1762 break;
1766 break;
1768 case presentation::ClickAction_STOPPRESENTATION :
1769 case presentation::ClickAction_SOUND :
1770 case presentation::ClickAction_INVISIBLE :
1771 case presentation::ClickAction_VERB :
1772 case presentation::ClickAction_VANISH :
1773 case presentation::ClickAction_MACRO :
1774 default :
1775 break;
1782 void ImplRenderPaintProc::createRedirectedPrimitive2DSequence(
1783 const sdr::contact::ViewObjectContact& rOriginal,
1784 const sdr::contact::DisplayInfo& rDisplayInfo,
1785 drawinglayer::primitive2d::Primitive2DDecompositionVisitor& rVisitor)
1787 SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
1788 if(!pObject)
1790 // not an object, maybe a page
1791 sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
1792 return;
1794 SdrPage* pSdrPage(pObject->getSdrPageFromSdrObject());
1795 if(!pSdrPage)
1796 return;
1797 if(!pSdrPage->checkVisibility(rOriginal, rDisplayInfo, false))
1798 return;
1799 if(!IsVisible(pObject) || !IsPrintable(pObject))
1800 return;
1802 sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo, rVisitor);
1805 bool ImplRenderPaintProc::IsVisible( const SdrObject* pObj ) const
1807 bool bVisible = true;
1808 SdrLayerID nLayerId = pObj->GetLayer();
1809 if( pSdrPageView )
1811 const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
1812 if ( pSdrLayer )
1814 const OUString& aLayerName = pSdrLayer->GetName();
1815 bVisible = pSdrPageView->IsLayerVisible( aLayerName );
1818 return bVisible;
1820 bool ImplRenderPaintProc::IsPrintable( const SdrObject* pObj ) const
1822 bool bPrintable = true;
1823 SdrLayerID nLayerId = pObj->GetLayer();
1824 if( pSdrPageView )
1826 const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
1827 if ( pSdrLayer )
1829 const OUString& aLayerName = pSdrLayer->GetName();
1830 bPrintable = pSdrPageView->IsLayerPrintable( aLayerName );
1833 return bPrintable;
1837 namespace
1839 sal_Int16 CalcOutputPageNum(vcl::PDFExtOutDevData const * pPDFExtOutDevData, SdDrawDocument const *pDoc, sal_Int16 nPageNumber)
1841 //export all pages, simple one to one case
1842 if (pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides())
1843 return nPageNumber-1;
1844 //check all preceding pages, and only count non-hidden ones
1845 sal_Int16 nRet = 0;
1846 for (sal_Int16 i = 0; i < nPageNumber-1; ++i)
1848 if (!pDoc->GetSdPage(i, PageKind::Standard)->IsExcluded())
1849 ++nRet;
1851 return nRet;
1855 void SAL_CALL SdXImpressDocument::render( sal_Int32 nRenderer, const uno::Any& rSelection,
1856 const uno::Sequence< beans::PropertyValue >& rxOptions )
1858 ::SolarMutexGuard aGuard;
1860 if( nullptr == mpDoc )
1861 throw lang::DisposedException();
1863 if (!mpDocShell)
1864 return;
1866 uno::Reference< awt::XDevice > xRenderDevice;
1867 const sal_Int32 nPageNumber = nRenderer + 1;
1868 PageKind ePageKind = PageKind::Standard;
1869 bool bExportNotesPages = false;
1871 for( const auto& rOption : rxOptions )
1873 if ( rOption.Name == "RenderDevice" )
1874 rOption.Value >>= xRenderDevice;
1875 else if ( rOption.Name == "ExportNotesPages" )
1877 rOption.Value >>= bExportNotesPages;
1878 if ( bExportNotesPages )
1879 ePageKind = PageKind::Notes;
1883 if( !(xRenderDevice.is() && nPageNumber && ( nPageNumber <= mpDoc->GetSdPageCount( ePageKind ) )) )
1884 return;
1886 VCLXDevice* pDevice = dynamic_cast<VCLXDevice*>( xRenderDevice.get() );
1887 VclPtr< OutputDevice> pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
1889 if( !pOut )
1890 return;
1892 vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData* >( pOut->GetExtOutDevData() );
1894 if ( mpDoc->GetSdPage(static_cast<sal_Int16>(nPageNumber)-1, PageKind::Standard)->IsExcluded() &&
1895 !(pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides()) )
1896 return;
1898 if (pPDFExtOutDevData)
1900 css::lang::Locale const docLocale(Application::GetSettings().GetLanguageTag().getLocale());
1901 pPDFExtOutDevData->SetDocumentLocale(docLocale);
1904 ::sd::ClientView aView( mpDocShell, pOut );
1905 ::tools::Rectangle aVisArea( Point(), mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind )->GetSize() );
1906 vcl::Region aRegion( aVisArea );
1908 ::sd::ViewShell* pOldViewSh = mpDocShell->GetViewShell();
1909 ::sd::View* pOldSdView = pOldViewSh ? pOldViewSh->GetView() : nullptr;
1911 if ( pOldSdView )
1912 pOldSdView->SdrEndTextEdit();
1914 aView.SetHlplVisible( false );
1915 aView.SetGridVisible( false );
1916 aView.SetBordVisible( false );
1917 aView.SetPageVisible( false );
1918 aView.SetGlueVisible( false );
1920 pOut->SetMapMode(MapMode(MapUnit::Map100thMM));
1921 pOut->IntersectClipRegion( aVisArea );
1923 uno::Reference< frame::XModel > xModel;
1924 rSelection >>= xModel;
1926 if( xModel == mpDocShell->GetModel() )
1928 aView.ShowSdrPage( mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind ));
1929 SdrPageView* pPV = aView.GetSdrPageView();
1931 if( pOldSdView )
1933 SdrPageView* pOldPV = pOldSdView->GetSdrPageView();
1934 if( pPV && pOldPV )
1936 pPV->SetVisibleLayers( pOldPV->GetVisibleLayers() );
1937 pPV->SetPrintableLayers( pOldPV->GetPrintableLayers() );
1941 ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
1942 pPV);
1944 // background color for outliner :o
1945 SdPage* pPage = pPV ? static_cast<SdPage*>(pPV->GetPage()) : nullptr;
1946 if( pPage )
1948 SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
1949 bool bScreenDisplay(true);
1951 // #i75566# printing; suppress AutoColor BackgroundColor generation
1952 // for visibility reasons by giving GetPageBackgroundColor()
1953 // the needed hint
1954 // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing)
1955 if (pOut && ((OUTDEV_PRINTER == pOut->GetOutDevType())
1956 || (OUTDEV_PDF == pOut->GetOutDevType())))
1957 bScreenDisplay = false;
1959 // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
1960 // hint value if screen display. Only then the AutoColor mechanisms shall be applied
1961 rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor( pPV, bScreenDisplay ) );
1964 // produce link annots for media shapes before painting them
1965 if ( pPDFExtOutDevData && pPage )
1969 uno::Any aAny;
1970 uno::Reference< drawing::XDrawPage > xPage( uno::Reference< drawing::XDrawPage >::query( pPage->getUnoPage() ) );
1971 if ( xPage.is() )
1973 if ( pPDFExtOutDevData->GetIsExportNotes() )
1974 ImplPDFExportComments( xPage, *pPDFExtOutDevData );
1975 uno::Reference< beans::XPropertySet > xPagePropSet( xPage, uno::UNO_QUERY );
1976 if( xPagePropSet.is() )
1978 // exporting object interactions to pdf
1980 // if necessary, the master page interactions will be exported first
1981 bool bIsBackgroundObjectsVisible = false; // #i39428# IsBackgroundObjectsVisible not available for Draw
1982 if ( mbImpressDoc && xPagePropSet->getPropertySetInfo()->hasPropertyByName( "IsBackgroundObjectsVisible" ) )
1983 xPagePropSet->getPropertyValue( "IsBackgroundObjectsVisible" ) >>= bIsBackgroundObjectsVisible;
1984 if ( bIsBackgroundObjectsVisible && !pPDFExtOutDevData->GetIsExportNotesPages() )
1986 uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( xPage, uno::UNO_QUERY );
1987 if ( xMasterPageTarget.is() )
1989 uno::Reference< drawing::XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage();
1990 if ( xMasterPage.is() )
1992 sal_Int32 i, nCount = xMasterPage->getCount();
1993 for ( i = 0; i < nCount; i++ )
1995 aAny = xMasterPage->getByIndex( i );
1996 uno::Reference< drawing::XShape > xShape;
1997 if ( aAny >>= xShape )
1998 ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
2004 // exporting slide page object interactions
2005 sal_Int32 i, nCount = xPage->getCount();
2006 for ( i = 0; i < nCount; i++ )
2008 aAny = xPage->getByIndex( i );
2009 uno::Reference< drawing::XShape > xShape;
2010 if ( aAny >>= xShape )
2011 ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
2014 // exporting transition effects to pdf
2015 if ( mbImpressDoc && !pPDFExtOutDevData->GetIsExportNotesPages() && pPDFExtOutDevData->GetIsExportTransitionEffects() )
2017 static const OUStringLiteral sEffect( u"Effect" );
2018 static const OUStringLiteral sSpeed ( u"Speed" );
2019 sal_Int32 nTime = 800;
2020 presentation::AnimationSpeed aAs;
2021 if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
2023 aAny = xPagePropSet->getPropertyValue( sSpeed );
2024 if ( aAny >>= aAs )
2026 switch( aAs )
2028 case presentation::AnimationSpeed_SLOW : nTime = 1500; break;
2029 case presentation::AnimationSpeed_FAST : nTime = 300; break;
2030 default:
2031 case presentation::AnimationSpeed_MEDIUM : nTime = 800;
2035 presentation::FadeEffect eFe;
2036 vcl::PDFWriter::PageTransition eType = vcl::PDFWriter::PageTransition::Regular;
2037 if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) )
2039 aAny = xPagePropSet->getPropertyValue( sEffect );
2040 if ( aAny >>= eFe )
2042 switch( eFe )
2044 case presentation::FadeEffect_HORIZONTAL_LINES :
2045 case presentation::FadeEffect_HORIZONTAL_CHECKERBOARD :
2046 case presentation::FadeEffect_HORIZONTAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsHorizontal; break;
2048 case presentation::FadeEffect_VERTICAL_LINES :
2049 case presentation::FadeEffect_VERTICAL_CHECKERBOARD :
2050 case presentation::FadeEffect_VERTICAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsVertical; break;
2052 case presentation::FadeEffect_UNCOVER_TO_RIGHT :
2053 case presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT :
2054 case presentation::FadeEffect_ROLL_FROM_LEFT :
2055 case presentation::FadeEffect_FADE_FROM_UPPERLEFT :
2056 case presentation::FadeEffect_MOVE_FROM_UPPERLEFT :
2057 case presentation::FadeEffect_FADE_FROM_LEFT :
2058 case presentation::FadeEffect_MOVE_FROM_LEFT : eType = vcl::PDFWriter::PageTransition::WipeLeftToRight; break;
2060 case presentation::FadeEffect_UNCOVER_TO_BOTTOM :
2061 case presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT :
2062 case presentation::FadeEffect_ROLL_FROM_TOP :
2063 case presentation::FadeEffect_FADE_FROM_UPPERRIGHT :
2064 case presentation::FadeEffect_MOVE_FROM_UPPERRIGHT :
2065 case presentation::FadeEffect_FADE_FROM_TOP :
2066 case presentation::FadeEffect_MOVE_FROM_TOP : eType = vcl::PDFWriter::PageTransition::WipeTopToBottom; break;
2068 case presentation::FadeEffect_UNCOVER_TO_LEFT :
2069 case presentation::FadeEffect_UNCOVER_TO_LOWERLEFT :
2070 case presentation::FadeEffect_ROLL_FROM_RIGHT :
2072 case presentation::FadeEffect_FADE_FROM_LOWERRIGHT :
2073 case presentation::FadeEffect_MOVE_FROM_LOWERRIGHT :
2074 case presentation::FadeEffect_FADE_FROM_RIGHT :
2075 case presentation::FadeEffect_MOVE_FROM_RIGHT : eType = vcl::PDFWriter::PageTransition::WipeRightToLeft; break;
2077 case presentation::FadeEffect_UNCOVER_TO_TOP :
2078 case presentation::FadeEffect_UNCOVER_TO_UPPERLEFT :
2079 case presentation::FadeEffect_ROLL_FROM_BOTTOM :
2080 case presentation::FadeEffect_FADE_FROM_LOWERLEFT :
2081 case presentation::FadeEffect_MOVE_FROM_LOWERLEFT :
2082 case presentation::FadeEffect_FADE_FROM_BOTTOM :
2083 case presentation::FadeEffect_MOVE_FROM_BOTTOM : eType = vcl::PDFWriter::PageTransition::WipeBottomToTop; break;
2085 case presentation::FadeEffect_OPEN_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalInward; break;
2086 case presentation::FadeEffect_CLOSE_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalOutward; break;
2088 case presentation::FadeEffect_OPEN_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalInward; break;
2089 case presentation::FadeEffect_CLOSE_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalOutward; break;
2091 case presentation::FadeEffect_FADE_TO_CENTER : eType = vcl::PDFWriter::PageTransition::BoxInward; break;
2092 case presentation::FadeEffect_FADE_FROM_CENTER : eType = vcl::PDFWriter::PageTransition::BoxOutward; break;
2094 case presentation::FadeEffect_NONE : eType = vcl::PDFWriter::PageTransition::Regular; break;
2096 case presentation::FadeEffect_RANDOM :
2097 case presentation::FadeEffect_DISSOLVE :
2098 default: eType = vcl::PDFWriter::PageTransition::Dissolve; break;
2103 if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) ||
2104 xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
2106 pPDFExtOutDevData->SetPageTransition( eType, nTime );
2112 catch (const uno::Exception&)
2117 aView.SdrPaintView::CompleteRedraw(pOut, aRegion, &aImplRenderPaintProc);
2119 if (pPDFExtOutDevData && pPage)
2123 Size aPageSize( mpDoc->GetSdPage( 0, PageKind::Standard )->GetSize() );
2124 Point aPoint( 0, 0 );
2125 ::tools::Rectangle aPageRect( aPoint, aPageSize );
2127 // resolving links found in this page by the method ImpEditEngine::Paint
2128 std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
2129 for ( const auto& rBookmark : rBookmarks )
2131 sal_Int32 nPage = ImplPDFGetBookmarkPage( rBookmark.aBookmark, *mpDoc );
2132 if ( nPage != -1 )
2134 if ( rBookmark.nLinkId != -1 )
2135 pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, pPDFExtOutDevData->CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle ) );
2136 else
2137 pPDFExtOutDevData->DescribeRegisteredDest( rBookmark.nDestId, aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle );
2139 else
2140 pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, rBookmark.aBookmark );
2142 rBookmarks.clear();
2143 //---> #i56629, #i40318
2144 //get the page name, will be used as outline element in PDF bookmark pane
2145 OUString aPageName = mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1 , PageKind::Standard )->GetName();
2146 if( !aPageName.isEmpty() )
2148 // Destination PageNum
2149 const sal_Int32 nDestPageNum = CalcOutputPageNum(pPDFExtOutDevData, mpDoc, nPageNumber);
2151 // insert the bookmark to this page into the NamedDestinations
2152 if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
2153 pPDFExtOutDevData->CreateNamedDest(aPageName, aPageRect, nDestPageNum);
2155 // add the name to the outline, (almost) same code as in sc/source/ui/unoobj/docuno.cxx
2156 // issue #i40318.
2158 if( pPDFExtOutDevData->GetIsExportBookmarks() )
2160 // Destination Export
2161 const sal_Int32 nDestId =
2162 pPDFExtOutDevData->CreateDest(aPageRect , nDestPageNum);
2164 // Create a new outline item:
2165 pPDFExtOutDevData->CreateOutlineItem( -1 , aPageName, nDestId );
2168 //<--- #i56629, #i40318
2170 catch (const uno::Exception&)
2176 else
2178 uno::Reference< drawing::XShapes > xShapes;
2179 rSelection >>= xShapes;
2181 if( xShapes.is() && xShapes->getCount() )
2183 SdrPageView* pPV = nullptr;
2185 ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
2186 pOldSdView ? pOldSdView->GetSdrPageView() : nullptr);
2188 for( sal_uInt32 i = 0, nCount = xShapes->getCount(); i < nCount; i++ )
2190 uno::Reference< drawing::XShape > xShape;
2191 xShapes->getByIndex( i ) >>= xShape;
2193 if( xShape.is() )
2195 SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape );
2196 if( pObj && pObj->getSdrPageFromSdrObject()
2197 && aImplRenderPaintProc.IsVisible( pObj )
2198 && aImplRenderPaintProc.IsPrintable( pObj ) )
2200 if( !pPV )
2201 pPV = aView.ShowSdrPage( pObj->getSdrPageFromSdrObject() );
2203 if( pPV )
2204 aView.MarkObj( pObj, pPV );
2208 aView.DrawMarkedObj(*pOut);
2213 DrawViewShell* SdXImpressDocument::GetViewShell()
2215 DrawViewShell* pViewSh = dynamic_cast<DrawViewShell*>(mpDocShell->GetViewShell());
2216 if (!pViewSh)
2218 SAL_WARN("sd", "DrawViewShell not available!");
2219 return nullptr;
2221 return pViewSh;
2224 void SdXImpressDocument::paintTile( VirtualDevice& rDevice,
2225 int nOutputWidth, int nOutputHeight,
2226 int nTilePosX, int nTilePosY,
2227 ::tools::Long nTileWidth, ::tools::Long nTileHeight )
2229 DrawViewShell* pViewSh = GetViewShell();
2230 if (!pViewSh)
2231 return;
2233 // we need to skip tile invalidation for controls on rendering
2234 comphelper::LibreOfficeKit::setTiledPainting(true);
2236 // Setup drawing layer to work properly. Since we use a custom VirtualDevice
2237 // for the drawing, SdrPaintView::BeginCompleteRedraw() will call FindPaintWindow()
2238 // unsuccessfully and use a temporary window that doesn't keep state. So patch
2239 // the existing SdrPageWindow to use a temporary, and this way the state will be kept.
2240 // Well, at least that's how I understand it based on Writer's RenderContextGuard,
2241 // as the drawing layer classes lack documentation.
2242 SdrPageWindow* patchedPageWindow = nullptr;
2243 SdrPaintWindow* previousPaintWindow = nullptr;
2244 std::unique_ptr<SdrPaintWindow> temporaryPaintWindow;
2245 if(SdrView* pDrawView = pViewSh->GetDrawView())
2247 if(SdrPageView* pSdrPageView = pDrawView->GetSdrPageView())
2249 pSdrPageView->SetApplicationDocumentColor(pViewSh->GetViewOptions().mnDocBackgroundColor);
2250 patchedPageWindow = pSdrPageView->FindPageWindow(*getDocWindow()->GetOutDev());
2251 temporaryPaintWindow.reset(new SdrPaintWindow(*pDrawView, rDevice));
2252 if (patchedPageWindow)
2253 previousPaintWindow = patchedPageWindow->patchPaintWindow(*temporaryPaintWindow);
2257 // Scaling. Must convert from pixels to twips. We know
2258 // that VirtualDevices use a DPI of 96.
2259 // We specifically calculate these scales first as we're still
2260 // in TWIPs, and might as well minimize the number of conversions.
2261 const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::twip);
2262 Fraction scaleX = Fraction(nOutputWidth, nTileWidth) * scale;
2263 Fraction scaleY = Fraction(nOutputHeight, nTileHeight) * scale;
2265 // svx seems to be the only component that works natively in
2266 // 100th mm rather than TWIP. It makes most sense just to
2267 // convert here and in getDocumentSize, and leave the tiled
2268 // rendering API working in TWIPs.
2269 ::tools::Long nTileWidthHMM = convertTwipToMm100( nTileWidth );
2270 ::tools::Long nTileHeightHMM = convertTwipToMm100( nTileHeight );
2271 int nTilePosXHMM = convertTwipToMm100( nTilePosX );
2272 int nTilePosYHMM = convertTwipToMm100( nTilePosY );
2274 MapMode aMapMode = rDevice.GetMapMode();
2275 aMapMode.SetMapUnit( MapUnit::Map100thMM );
2276 aMapMode.SetOrigin( Point( -nTilePosXHMM,
2277 -nTilePosYHMM) );
2278 aMapMode.SetScaleX( scaleX );
2279 aMapMode.SetScaleY( scaleY );
2281 rDevice.SetMapMode( aMapMode );
2283 rDevice.SetOutputSizePixel( Size(nOutputWidth, nOutputHeight) );
2285 Point aPoint(nTilePosXHMM, nTilePosYHMM);
2286 Size aSize(nTileWidthHMM, nTileHeightHMM);
2287 ::tools::Rectangle aRect(aPoint, aSize);
2289 SdrView* pView = pViewSh->GetDrawView();
2290 if (comphelper::LibreOfficeKit::isActive())
2291 pView->SetPaintTextEdit(mbPaintTextEdit);
2293 pViewSh->GetView()->CompleteRedraw(&rDevice, vcl::Region(aRect));
2295 if (comphelper::LibreOfficeKit::isActive())
2296 pView->SetPaintTextEdit(true);
2298 LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
2299 nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2300 LokStarMathHelper::PaintAllInPlaceOnTile(rDevice, nOutputWidth, nOutputHeight, nTilePosX,
2301 nTilePosY, nTileWidth, nTileHeight);
2303 if(patchedPageWindow != nullptr)
2304 patchedPageWindow->unpatchPaintWindow(previousPaintWindow);
2306 // Draw Form controls
2307 SdrView* pDrawView = pViewSh->GetDrawView();
2308 SdrPageView* pPageView = pDrawView->GetSdrPageView();
2309 if (pPageView != nullptr)
2311 SdrPage* pPage = pPageView->GetPage();
2312 ::sd::Window* pActiveWin = pViewSh->GetActiveWindow();
2313 ::tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight));
2314 Size aOutputSize(nOutputWidth, nOutputHeight);
2315 LokControlHandler::paintControlTile(pPage, pDrawView, *pActiveWin, rDevice, aOutputSize, aTileRect);
2318 comphelper::LibreOfficeKit::setTiledPainting(false);
2321 OString SdXImpressDocument::getViewRenderState()
2323 OStringBuffer aState;
2324 DrawViewShell* pView = GetViewShell();
2325 if (pView)
2327 const SdViewOptions& pVOpt = pView->GetViewOptions();
2328 aState.append(';');
2330 OString aThemeName = OUStringToOString(pVOpt.msColorSchemeName, RTL_TEXTENCODING_UTF8);
2331 aState.append(aThemeName);
2333 return aState.makeStringAndClear();
2336 void SdXImpressDocument::selectPart(int nPart, int nSelect)
2338 DrawViewShell* pViewSh = GetViewShell();
2339 if (!pViewSh)
2340 return;
2342 pViewSh->SelectPage(nPart, nSelect);
2345 void SdXImpressDocument::moveSelectedParts(int nPosition, bool bDuplicate)
2347 // Duplicating is currently unsupported.
2348 if (!bDuplicate)
2349 mpDoc->MovePages(nPosition);
2352 OUString SdXImpressDocument::getPartInfo(int nPart)
2354 DrawViewShell* pViewSh = GetViewShell();
2355 if (!pViewSh)
2356 return OUString();
2358 const bool bIsVisible = pViewSh->IsVisible(nPart);
2359 const bool bIsSelected = pViewSh->IsSelected(nPart);
2360 const sal_Int16 nMasterPageCount= pViewSh->GetDoc()->GetMasterSdPageCount(pViewSh->GetPageKind());
2362 OUString aPartInfo = "{ \"visible\": \"" +
2363 OUString::number(static_cast<unsigned int>(bIsVisible)) +
2364 "\", \"selected\": \"" +
2365 OUString::number(static_cast<unsigned int>(bIsSelected)) +
2366 "\", \"masterPageCount\": \"" +
2367 OUString::number(nMasterPageCount) +
2368 "\", \"mode\": \"" +
2369 OUString::number(getEditMode()) +
2370 "\" }";
2372 return aPartInfo;
2375 void SdXImpressDocument::setPart( int nPart, bool bAllowChangeFocus )
2377 DrawViewShell* pViewSh = GetViewShell();
2378 if (!pViewSh)
2379 return;
2381 pViewSh->SwitchPage( nPart, bAllowChangeFocus );
2384 int SdXImpressDocument::getParts()
2386 if (!mpDoc)
2387 return 0;
2389 if (isMasterViewMode())
2390 return mpDoc->GetMasterSdPageCount(PageKind::Standard);
2392 return mpDoc->GetSdPageCount(PageKind::Standard);
2395 int SdXImpressDocument::getPart()
2397 DrawViewShell* pViewSh = GetViewShell();
2398 if (!pViewSh)
2399 return 0;
2401 return pViewSh->GetViewShellBase().getPart();
2404 OUString SdXImpressDocument::getPartName(int nPart)
2406 SdPage* pPage;
2407 if (isMasterViewMode())
2408 pPage = mpDoc->GetMasterSdPage(nPart, PageKind::Standard);
2409 else
2410 pPage = mpDoc->GetSdPage(nPart, PageKind::Standard);
2412 if (!pPage)
2414 SAL_WARN("sd", "DrawViewShell not available!");
2415 return OUString();
2418 return pPage->GetName();
2421 OUString SdXImpressDocument::getPartHash(int nPart)
2423 SdPage* pPage;
2424 if (isMasterViewMode())
2425 pPage = mpDoc->GetMasterSdPage(nPart, PageKind::Standard);
2426 else
2427 pPage = mpDoc->GetSdPage(nPart, PageKind::Standard);
2429 if (!pPage)
2431 SAL_WARN("sd", "DrawViewShell not available!");
2432 return OUString();
2435 return OUString::number(pPage->GetHashCode());
2438 bool SdXImpressDocument::isMasterViewMode()
2440 DrawViewShell* pViewSh = GetViewShell();
2441 if (!pViewSh)
2442 return false;
2444 if (pViewSh->GetDispatcher())
2446 const SfxBoolItem* isMasterViewMode = nullptr;
2447 pViewSh->GetDispatcher()->QueryState(SID_SLIDE_MASTER_MODE, isMasterViewMode);
2448 if (isMasterViewMode && isMasterViewMode->GetValue())
2449 return true;
2451 return false;
2454 VclPtr<vcl::Window> SdXImpressDocument::getDocWindow()
2456 SolarMutexGuard aGuard;
2457 DrawViewShell* pViewShell = GetViewShell();
2458 if (!pViewShell)
2459 return {};
2461 if (VclPtr<vcl::Window> pWindow = SfxLokHelper::getInPlaceDocWindow(pViewShell->GetViewShell()))
2462 return pWindow;
2464 return pViewShell->GetActiveWindow();
2467 void SdXImpressDocument::setPartMode( int nPartMode )
2469 DrawViewShell* pViewSh = GetViewShell();
2470 if (!pViewSh)
2471 return;
2473 PageKind aPageKind( PageKind::Standard );
2474 switch ( nPartMode )
2476 case LOK_PARTMODE_SLIDES:
2477 break;
2478 case LOK_PARTMODE_NOTES:
2479 aPageKind = PageKind::Notes;
2480 break;
2482 pViewSh->SetPageKind( aPageKind );
2485 int SdXImpressDocument::getEditMode()
2487 DrawViewShell* pViewSh = GetViewShell();
2488 if (!pViewSh)
2489 return 0;
2491 return pViewSh->GetViewShellBase().getEditMode();
2494 void SdXImpressDocument::setEditMode(int nMode)
2496 SolarMutexGuard aGuard;
2498 DrawViewShell* pViewSh = GetViewShell();
2499 if (!pViewSh)
2500 return;
2502 pViewSh->GetViewShellBase().setEditMode(nMode);
2505 Size SdXImpressDocument::getDocumentSize()
2507 DrawViewShell* pViewSh = GetViewShell();
2508 if (!pViewSh)
2509 return Size();
2511 SdrView *pSdrView = pViewSh->GetView();
2512 if (!pSdrView)
2513 return Size();
2515 SdrPageView* pCurPageView = pSdrView->GetSdrPageView();
2516 if (!pCurPageView)
2517 return Size();
2519 Size aSize = pCurPageView->GetPageRect().GetSize();
2520 // Convert the size in 100th mm to TWIP
2521 // See paintTile above for further info.
2522 return o3tl::convert(aSize, o3tl::Length::mm100, o3tl::Length::twip);
2525 void SdXImpressDocument::getPostIts(::tools::JsonWriter& rJsonWriter)
2527 auto commentsNode = rJsonWriter.startNode("comments");
2528 // Return annotations on master pages too ?
2529 const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
2530 SdPage* pPage;
2531 for (sal_uInt16 nPage = 0; nPage < nMaxPages; ++nPage)
2533 pPage = static_cast<SdPage*>(mpDoc->GetPage(nPage));
2534 const sd::AnnotationVector& aPageAnnotations = pPage->getAnnotations();
2536 for (const uno::Reference<office::XAnnotation>& xAnnotation : aPageAnnotations)
2538 sal_uInt32 nID = sd::getAnnotationId(xAnnotation);
2539 OString nodeName = "comment" + OString::number(nID);
2540 auto commentNode = rJsonWriter.startNode(nodeName);
2541 rJsonWriter.put("id", nID);
2542 rJsonWriter.put("author", xAnnotation->getAuthor());
2543 rJsonWriter.put("dateTime", utl::toISO8601(xAnnotation->getDateTime()));
2544 uno::Reference<text::XText> xText(xAnnotation->getTextRange());
2545 rJsonWriter.put("text", xText->getString());
2546 rJsonWriter.put("parthash", pPage->GetHashCode());
2547 geometry::RealPoint2D const & rPoint = xAnnotation->getPosition();
2548 geometry::RealSize2D const & rSize = xAnnotation->getSize();
2549 ::tools::Rectangle aRectangle(Point(rPoint.X * 100.0, rPoint.Y * 100.0), Size(rSize.Width * 100.0, rSize.Height * 100.0));
2550 aRectangle = o3tl::toTwips(aRectangle, o3tl::Length::mm100);
2551 OString sRectangle = aRectangle.toString();
2552 rJsonWriter.put("rectangle", sRectangle.getStr());
2557 void SdXImpressDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
2559 SolarMutexGuard aGuard;
2561 if (DrawViewShell* pViewShell = GetViewShell())
2563 DrawView* pDrawView = pViewShell->GetDrawView();
2564 for (const beans::PropertyValue& rValue : rArguments)
2566 if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
2567 pDrawView->SetPageShadowVisible(rValue.Value.get<bool>());
2568 else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
2569 pDrawView->SetAuthor(rValue.Value.get<OUString>());
2570 else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
2571 mpDoc->SetOnlineSpell(rValue.Value.get<bool>());
2574 // Disable comments if requested
2575 SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
2576 pOptions->SetShowComments(comphelper::LibreOfficeKit::isTiledAnnotations());
2578 pViewShell->SetRuler(false);
2579 pViewShell->SetScrollBarsVisible(false);
2581 if (sd::Window* pWindow = pViewShell->GetActiveWindow())
2583 // get the full page size in pixels
2584 pWindow->EnableMapMode();
2585 Size aSize(pWindow->LogicToPixel(pDrawView->GetSdrPageView()->GetPage()->GetSize()));
2586 // Disable map mode, so that it's possible to send mouse event
2587 // coordinates in logic units
2588 pWindow->EnableMapMode(false);
2590 // arrange UI elements again with new view size
2591 pViewShell->GetParentWindow()->SetSizePixel(aSize);
2592 pViewShell->Resize();
2595 // Forces all images to be swapped in synchronously, this
2596 // ensures that images are available when paintTile is called
2597 // (whereas with async loading images start being loaded after
2598 // we have painted the tile, resulting in an invalidate, followed
2599 // by the tile being rerendered - which is wasteful and ugly).
2600 pDrawView->SetSwapAsynchron(false);
2603 // when the "This document may contain formatting or content that cannot
2604 // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
2605 // causing 'Save' being disabled; so let's always save to the original
2606 // format
2607 auto xChanges = comphelper::ConfigurationChanges::create();
2608 officecfg::Office::Common::Save::Document::WarnAlienFormat::set(false, xChanges);
2609 xChanges->commit();
2611 if (!getenv("LO_TESTNAME"))
2612 SvtSlideSorterBarOptions().SetVisibleImpressView(true);
2615 void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
2617 SolarMutexGuard aGuard;
2618 SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
2621 void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
2623 SolarMutexGuard aGuard;
2625 DrawViewShell* pViewShell = GetViewShell();
2626 if (!pViewShell)
2627 return;
2629 constexpr double fScale = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::px);
2631 if (SfxLokHelper::testInPlaceComponentMouseEventHit(
2632 pViewShell->GetViewShell(), nType, nX, nY, nCount, nButtons, nModifier, fScale, fScale))
2633 return;
2635 // try to forward mouse event to control
2636 const Point aPointTwip(nX, nY);
2637 const Point aPointHMM = o3tl::convert(aPointTwip, o3tl::Length::twip, o3tl::Length::mm100);
2638 SdrView* pDrawView = pViewShell->GetDrawView();
2639 SdrPageView* pPageView = pDrawView->GetSdrPageView();
2640 SdrPage* pPage = pPageView->GetPage();
2641 ::sd::Window* pActiveWin = pViewShell->GetActiveWindow();
2642 if (!pActiveWin)
2644 return;
2647 if (LokControlHandler::postMouseEvent(pPage, pDrawView, *pActiveWin, nType, aPointHMM, nCount, nButtons, nModifier))
2648 return;
2650 LokMouseEventData aMouseEventData(nType, aPointHMM, nCount, MouseEventModifiers::SIMPLECLICK,
2651 nButtons, nModifier);
2652 SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), aMouseEventData);
2655 void SdXImpressDocument::setTextSelection(int nType, int nX, int nY)
2657 SolarMutexGuard aGuard;
2659 DrawViewShell* pViewShell = GetViewShell();
2660 if (!pViewShell)
2661 return;
2663 LokChartHelper aChartHelper(pViewShell->GetViewShell());
2664 if (aChartHelper.setTextSelection(nType, nX, nY))
2665 return;
2667 Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
2668 switch (nType)
2670 case LOK_SETTEXTSELECTION_START:
2671 pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
2672 break;
2673 case LOK_SETTEXTSELECTION_END:
2674 pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
2675 break;
2676 case LOK_SETTEXTSELECTION_RESET:
2677 pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
2678 break;
2679 default:
2680 assert(false);
2681 break;
2685 uno::Reference<datatransfer::XTransferable> SdXImpressDocument::getSelection()
2687 SolarMutexGuard aGuard;
2689 DrawViewShell* pViewShell = GetViewShell();
2690 if (!pViewShell)
2691 return uno::Reference<datatransfer::XTransferable>();
2693 return pViewShell->GetSelectionTransferable();
2696 void SdXImpressDocument::setGraphicSelection(int nType, int nX, int nY)
2698 SolarMutexGuard aGuard;
2700 DrawViewShell* pViewShell = GetViewShell();
2701 if (!pViewShell)
2702 return;
2704 constexpr double fScale = o3tl::convert(1.0, o3tl::Length::twip, o3tl::Length::px);
2706 LokChartHelper aChartHelper(pViewShell->GetViewShell());
2707 if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
2708 return;
2710 Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
2711 switch (nType)
2713 case LOK_SETGRAPHICSELECTION_START:
2714 pViewShell->SetGraphicMm100Position(/*bStart=*/true, aPoint);
2715 break;
2716 case LOK_SETGRAPHICSELECTION_END:
2717 pViewShell->SetGraphicMm100Position(/*bStart=*/false, aPoint);
2718 break;
2719 default:
2720 assert(false);
2721 break;
2725 void SdXImpressDocument::resetSelection()
2727 SolarMutexGuard aGuard;
2729 DrawViewShell* pViewShell = GetViewShell();
2730 if (!pViewShell)
2731 return;
2733 SdrView* pSdrView = pViewShell->GetView();
2734 if (!pSdrView)
2735 return;
2737 if (pSdrView->IsTextEdit())
2739 // Reset the editeng selection.
2740 pSdrView->UnmarkAll();
2741 // Finish editing.
2742 pSdrView->SdrEndTextEdit();
2744 // Reset graphic selection.
2745 pSdrView->UnmarkAll();
2748 void SdXImpressDocument::setClientVisibleArea(const ::tools::Rectangle& rRectangle)
2750 SolarMutexGuard aGuard;
2752 DrawViewShell* pViewShell = GetViewShell();
2753 if (!pViewShell)
2754 return;
2756 pViewShell->GetViewShellBase().setLOKVisibleArea(rRectangle);
2759 void SdXImpressDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
2761 SolarMutexGuard aGuard;
2763 DrawViewShell* pViewShell = GetViewShell();
2764 if (!pViewShell)
2765 return;
2767 pViewShell->GetActiveWindow()->SetClipboard(xClipboard);
2770 bool SdXImpressDocument::isMimeTypeSupported()
2772 SolarMutexGuard aGuard;
2773 DrawViewShell* pViewShell = GetViewShell();
2774 if (!pViewShell)
2775 return false;
2777 TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewShell->GetActiveWindow()));
2778 return EditEngine::HasValidData(aDataHelper.GetTransferable());
2781 PointerStyle SdXImpressDocument::getPointer()
2783 SolarMutexGuard aGuard;
2784 DrawViewShell* pViewShell = GetViewShell();
2785 if (!pViewShell)
2786 return PointerStyle::Arrow;
2788 Window* pWindow = pViewShell->GetActiveWindow();
2789 if (!pWindow)
2790 return PointerStyle::Arrow;
2792 return pWindow->GetPointer();
2795 uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable()
2797 uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbiddenCharacters);
2799 if( !xForb.is() )
2800 mxForbiddenCharacters = xForb = new SdUnoForbiddenCharsTable( mpDoc );
2802 return xForb;
2805 void SdXImpressDocument::initializeDocument()
2807 if( mbClipBoard )
2808 return;
2810 switch( mpDoc->GetPageCount() )
2812 case 1:
2814 // nasty hack to detect clipboard document
2815 mbClipBoard = true;
2816 break;
2818 case 0:
2820 mpDoc->CreateFirstPages();
2821 mpDoc->StopWorkStartupDelay();
2822 break;
2827 SdrModel& SdXImpressDocument::getSdrModelFromUnoModel() const
2829 OSL_ENSURE(GetDoc(), "No SdrModel in draw/Impress, should not happen");
2830 return *GetDoc(); // TTTT should be reference
2833 void SAL_CALL SdXImpressDocument::dispose()
2835 if( mbDisposed )
2836 return;
2838 ::SolarMutexGuard aGuard;
2840 if( mpDoc )
2842 EndListening( *mpDoc );
2843 mpDoc = nullptr;
2846 // Call the base class dispose() before setting the mbDisposed flag
2847 // to true. The reason for this is that if close() has not yet been
2848 // called this is done in SfxBaseModel::dispose(). At the end of
2849 // that dispose() is called again. It is important to forward this
2850 // second dispose() to the base class, too.
2851 // As a consequence the following code has to be able to be run twice.
2852 SfxBaseModel::dispose();
2853 mbDisposed = true;
2855 uno::Reference< container::XNameAccess > xLinks( mxLinks );
2856 if( xLinks.is() )
2858 uno::Reference< lang::XComponent > xComp( xLinks, uno::UNO_QUERY );
2859 if( xComp.is() )
2860 xComp->dispose();
2862 xLinks = nullptr;
2865 uno::Reference< drawing::XDrawPages > xDrawPagesAccess( mxDrawPagesAccess );
2866 if( xDrawPagesAccess.is() )
2868 uno::Reference< lang::XComponent > xComp( xDrawPagesAccess, uno::UNO_QUERY );
2869 if( xComp.is() )
2870 xComp->dispose();
2872 xDrawPagesAccess = nullptr;
2875 uno::Reference< drawing::XDrawPages > xMasterPagesAccess( mxMasterPagesAccess );
2876 if( xDrawPagesAccess.is() )
2878 uno::Reference< lang::XComponent > xComp( xMasterPagesAccess, uno::UNO_QUERY );
2879 if( xComp.is() )
2880 xComp->dispose();
2882 xDrawPagesAccess = nullptr;
2885 uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager );
2886 if( xLayerManager.is() )
2888 uno::Reference< lang::XComponent > xComp( xLayerManager, uno::UNO_QUERY );
2889 if( xComp.is() )
2890 xComp->dispose();
2892 xLayerManager = nullptr;
2895 uno::Reference< container::XNameContainer > xCustomPresentationAccess( mxCustomPresentationAccess );
2896 if( xCustomPresentationAccess.is() )
2898 uno::Reference< lang::XComponent > xComp( xCustomPresentationAccess, uno::UNO_QUERY );
2899 if( xComp.is() )
2900 xComp->dispose();
2902 xCustomPresentationAccess = nullptr;
2905 mxDashTable = nullptr;
2906 mxGradientTable = nullptr;
2907 mxHatchTable = nullptr;
2908 mxBitmapTable = nullptr;
2909 mxTransGradientTable = nullptr;
2910 mxMarkerTable = nullptr;
2911 mxDrawingPool = nullptr;
2915 SdDrawPagesAccess::SdDrawPagesAccess( SdXImpressDocument& rMyModel ) noexcept
2916 : mpModel( &rMyModel)
2920 SdDrawPagesAccess::~SdDrawPagesAccess() noexcept
2924 // XIndexAccess
2925 sal_Int32 SAL_CALL SdDrawPagesAccess::getCount()
2927 ::SolarMutexGuard aGuard;
2929 if( nullptr == mpModel )
2930 throw lang::DisposedException();
2932 return mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2935 uno::Any SAL_CALL SdDrawPagesAccess::getByIndex( sal_Int32 Index )
2937 ::SolarMutexGuard aGuard;
2939 if( nullptr == mpModel )
2940 throw lang::DisposedException();
2942 uno::Any aAny;
2944 if( (Index < 0) || (Index >= mpModel->mpDoc->GetSdPageCount( PageKind::Standard ) ) )
2945 throw lang::IndexOutOfBoundsException();
2947 SdPage* pPage = mpModel->mpDoc->GetSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
2948 if( pPage )
2950 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2951 aAny <<= xDrawPage;
2954 return aAny;
2957 // XNameAccess
2958 uno::Any SAL_CALL SdDrawPagesAccess::getByName( const OUString& aName )
2960 ::SolarMutexGuard aGuard;
2962 if( nullptr == mpModel )
2963 throw lang::DisposedException();
2965 if( !aName.isEmpty() )
2967 const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2968 sal_uInt16 nPage;
2969 for( nPage = 0; nPage < nCount; nPage++ )
2971 SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2972 if(nullptr == pPage)
2973 continue;
2975 if( aName == SdDrawPage::getPageApiName( pPage ) )
2977 uno::Any aAny;
2978 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2979 aAny <<= xDrawPage;
2980 return aAny;
2985 throw container::NoSuchElementException();
2988 uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getElementNames()
2990 ::SolarMutexGuard aGuard;
2992 if( nullptr == mpModel )
2993 throw lang::DisposedException();
2995 const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2996 uno::Sequence< OUString > aNames( nCount );
2997 OUString* pNames = aNames.getArray();
2999 sal_uInt16 nPage;
3000 for( nPage = 0; nPage < nCount; nPage++ )
3002 SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
3003 *pNames++ = SdDrawPage::getPageApiName( pPage );
3006 return aNames;
3009 sal_Bool SAL_CALL SdDrawPagesAccess::hasByName( const OUString& aName )
3011 ::SolarMutexGuard aGuard;
3013 if( nullptr == mpModel )
3014 throw lang::DisposedException();
3016 const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
3017 sal_uInt16 nPage;
3018 for( nPage = 0; nPage < nCount; nPage++ )
3020 SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
3021 if(nullptr == pPage)
3022 continue;
3024 if( aName == SdDrawPage::getPageApiName( pPage ) )
3025 return true;
3028 return false;
3031 // XElementAccess
3032 uno::Type SAL_CALL SdDrawPagesAccess::getElementType()
3034 return cppu::UnoType<drawing::XDrawPage>::get();
3037 sal_Bool SAL_CALL SdDrawPagesAccess::hasElements()
3039 return getCount() > 0;
3042 // XDrawPages
3045 * Creates a new page with model at the specified position.
3046 * @returns corresponding SdDrawPage
3048 uno::Reference< drawing::XDrawPage > SAL_CALL SdDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex )
3050 ::SolarMutexGuard aGuard;
3051 comphelper::ProfileZone aZone("insertNewByIndex");
3053 if( nullptr == mpModel )
3054 throw lang::DisposedException();
3056 if( mpModel->mpDoc )
3058 SdPage* pPage = mpModel->InsertSdPage( static_cast<sal_uInt16>(nIndex), false );
3059 if( pPage )
3061 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
3062 return xDrawPage;
3065 uno::Reference< drawing::XDrawPage > xDrawPage;
3066 return xDrawPage;
3070 * Removes the specified SdDrawPage from the model and the internal list. It
3071 * only works, if there is at least one *normal* page in the model after
3072 * removing this page.
3074 void SAL_CALL SdDrawPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
3076 ::SolarMutexGuard aGuard;
3078 if( nullptr == mpModel || mpModel->mpDoc == nullptr )
3079 throw lang::DisposedException();
3081 SdDrawDocument& rDoc = *mpModel->mpDoc;
3083 sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard );
3084 if( nPageCount > 1 )
3086 // get pPage from xPage and determine the Id (nPos ) afterwards
3087 SdDrawPage* pSvxPage = comphelper::getFromUnoTunnel<SdDrawPage>( xPage );
3088 if( pSvxPage )
3090 SdPage* pPage = static_cast<SdPage*>(pSvxPage->GetSdrPage());
3091 if(pPage && ( pPage->GetPageKind() == PageKind::Standard ) )
3093 sal_uInt16 nPage = pPage->GetPageNum();
3095 SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetPage( nPage+1 ) );
3097 bool bUndo = rDoc.IsUndoEnabled();
3098 if( bUndo )
3100 // Add undo actions and delete the pages. The order of adding
3101 // the undo actions is important.
3102 rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
3103 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
3104 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
3107 rDoc.RemovePage( nPage ); // the page
3108 rDoc.RemovePage( nPage ); // the notes page
3110 if( bUndo )
3112 rDoc.EndUndo();
3118 mpModel->SetModified();
3121 // XServiceInfo
3123 OUString SAL_CALL SdDrawPagesAccess::getImplementationName( )
3125 return "SdDrawPagesAccess";
3128 sal_Bool SAL_CALL SdDrawPagesAccess::supportsService( const OUString& ServiceName )
3130 return cppu::supportsService(this, ServiceName);
3133 uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getSupportedServiceNames( )
3135 return { "com.sun.star.drawing.DrawPages" };
3138 // XComponent
3139 void SAL_CALL SdDrawPagesAccess::dispose( )
3141 mpModel = nullptr;
3144 void SAL_CALL SdDrawPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >& )
3146 OSL_FAIL( "not implemented!" );
3149 void SAL_CALL SdDrawPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >& )
3151 OSL_FAIL( "not implemented!" );
3155 SdMasterPagesAccess::SdMasterPagesAccess( SdXImpressDocument& rMyModel ) noexcept
3156 : mpModel(&rMyModel)
3160 SdMasterPagesAccess::~SdMasterPagesAccess() noexcept
3164 // XComponent
3165 void SAL_CALL SdMasterPagesAccess::dispose( )
3167 mpModel = nullptr;
3170 void SAL_CALL SdMasterPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >& )
3172 OSL_FAIL( "not implemented!" );
3175 void SAL_CALL SdMasterPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >& )
3177 OSL_FAIL( "not implemented!" );
3180 // XIndexAccess
3181 sal_Int32 SAL_CALL SdMasterPagesAccess::getCount()
3183 ::SolarMutexGuard aGuard;
3185 if( nullptr == mpModel->mpDoc )
3186 throw lang::DisposedException();
3188 return mpModel->mpDoc->GetMasterSdPageCount(PageKind::Standard);
3192 * Provides a drawing::XDrawPage interface for accessing the Masterpage at the
3193 * specified position in the model.
3195 uno::Any SAL_CALL SdMasterPagesAccess::getByIndex( sal_Int32 Index )
3197 ::SolarMutexGuard aGuard;
3198 comphelper::ProfileZone aZone("SdMasterPagesAccess::getByIndex");
3200 if( nullptr == mpModel )
3201 throw lang::DisposedException();
3203 uno::Any aAny;
3205 if( (Index < 0) || (Index >= mpModel->mpDoc->GetMasterSdPageCount( PageKind::Standard ) ) )
3206 throw lang::IndexOutOfBoundsException();
3208 SdPage* pPage = mpModel->mpDoc->GetMasterSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
3209 if( pPage )
3211 uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
3212 aAny <<= xDrawPage;
3215 return aAny;
3218 // XElementAccess
3219 uno::Type SAL_CALL SdMasterPagesAccess::getElementType()
3221 return cppu::UnoType<drawing::XDrawPage>::get();
3224 sal_Bool SAL_CALL SdMasterPagesAccess::hasElements()
3226 return getCount() > 0;
3229 // XDrawPages
3230 uno::Reference< drawing::XDrawPage > SAL_CALL SdMasterPagesAccess::insertNewByIndex( sal_Int32 nInsertPos )
3232 ::SolarMutexGuard aGuard;
3234 if( nullptr == mpModel )
3235 throw lang::DisposedException();
3237 uno::Reference< drawing::XDrawPage > xDrawPage;
3239 SdDrawDocument* pDoc = mpModel->mpDoc;
3240 if( pDoc )
3242 // calculate internal index and check for range errors
3243 const sal_Int32 nMPageCount = pDoc->GetMasterPageCount();
3244 nInsertPos = nInsertPos * 2 + 1;
3245 if( nInsertPos < 0 || nInsertPos > nMPageCount )
3246 nInsertPos = nMPageCount;
3248 // now generate a unique name for the new masterpage
3249 const OUString aStdPrefix( SdResId(STR_LAYOUT_DEFAULT_NAME) );
3250 OUString aPrefix( aStdPrefix );
3252 bool bUnique = true;
3254 std::vector<OUString> aPageNames;
3255 for (sal_Int32 nMaster = 1; nMaster < nMPageCount; ++nMaster)
3257 const SdPage* pPage = static_cast<const SdPage*>(pDoc->GetMasterPage(static_cast<sal_uInt16>(nMaster)));
3258 if (!pPage)
3259 continue;
3260 aPageNames.push_back(pPage->GetName());
3261 if (aPageNames.back() == aPrefix)
3262 bUnique = false;
3265 sal_Int32 i = 0;
3266 while (!bUnique)
3268 aPrefix = aStdPrefix + " " + OUString::number(++i);
3269 bUnique = std::find(aPageNames.begin(), aPageNames.end(), aPrefix) == aPageNames.end();
3272 OUString aLayoutName = aPrefix + SD_LT_SEPARATOR + STR_LAYOUT_OUTLINE;
3274 // create styles
3275 static_cast<SdStyleSheetPool*>(pDoc->GetStyleSheetPool())->CreateLayoutStyleSheets( aPrefix );
3277 // get the first page for initial size and border settings
3278 SdPage* pPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Standard );
3279 SdPage* pRefNotesPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Notes);
3281 // create and insert new draw masterpage
3282 rtl::Reference<SdPage> pMPage = mpModel->mpDoc->AllocSdPage(true);
3283 pMPage->SetSize( pPage->GetSize() );
3284 pMPage->SetBorder( pPage->GetLeftBorder(),
3285 pPage->GetUpperBorder(),
3286 pPage->GetRightBorder(),
3287 pPage->GetLowerBorder() );
3288 pMPage->SetLayoutName( aLayoutName );
3289 pDoc->InsertMasterPage(pMPage.get(), static_cast<sal_uInt16>(nInsertPos));
3292 // ensure default MasterPage fill
3293 pMPage->EnsureMasterPageDefaultBackground();
3296 xDrawPage.set( pMPage->getUnoPage(), uno::UNO_QUERY );
3298 // create and insert new notes masterpage
3299 rtl::Reference<SdPage> pMNotesPage = mpModel->mpDoc->AllocSdPage(true);
3300 pMNotesPage->SetSize( pRefNotesPage->GetSize() );
3301 pMNotesPage->SetPageKind(PageKind::Notes);
3302 pMNotesPage->SetBorder( pRefNotesPage->GetLeftBorder(),
3303 pRefNotesPage->GetUpperBorder(),
3304 pRefNotesPage->GetRightBorder(),
3305 pRefNotesPage->GetLowerBorder() );
3306 pMNotesPage->SetLayoutName( aLayoutName );
3307 pDoc->InsertMasterPage(pMNotesPage.get(), static_cast<sal_uInt16>(nInsertPos) + 1);
3308 pMNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
3309 mpModel->SetModified();
3312 return xDrawPage;
3316 * Removes the specified SdMasterPage from the model and the internal list. It
3317 * only works, if there is no *normal* page using this page as MasterPage in
3318 * the model.
3320 void SAL_CALL SdMasterPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
3322 ::SolarMutexGuard aGuard;
3324 if( nullptr == mpModel || mpModel->mpDoc == nullptr )
3325 throw lang::DisposedException();
3327 SdMasterPage* pSdPage = comphelper::getFromUnoTunnel<SdMasterPage>( xPage );
3328 if(pSdPage == nullptr)
3329 return;
3331 SdPage* pPage = dynamic_cast< SdPage* > (pSdPage->GetSdrPage());
3333 DBG_ASSERT( pPage && pPage->IsMasterPage(), "SdMasterPage is not masterpage?");
3335 if( !pPage || !pPage->IsMasterPage() || (mpModel->mpDoc->GetMasterPageUserCount(pPage) > 0))
3336 return; //Todo: this should be excepted
3338 // only standard pages can be removed directly
3339 if( pPage->GetPageKind() != PageKind::Standard )
3340 return;
3342 sal_uInt16 nPage = pPage->GetPageNum();
3344 SdDrawDocument& rDoc = *mpModel->mpDoc;
3346 SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetMasterPage( nPage+1 ) );
3348 bool bUndo = rDoc.IsUndoEnabled();
3349 if( bUndo )
3351 // Add undo actions and delete the pages. The order of adding
3352 // the undo actions is important.
3353 rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
3354 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
3355 rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
3358 // remove both pages
3359 rDoc.RemoveMasterPage( nPage );
3360 rDoc.RemoveMasterPage( nPage );
3362 if( bUndo )
3364 rDoc.EndUndo();
3368 // XServiceInfo
3370 OUString SAL_CALL SdMasterPagesAccess::getImplementationName( )
3372 return "SdMasterPagesAccess";
3375 sal_Bool SAL_CALL SdMasterPagesAccess::supportsService( const OUString& ServiceName )
3377 return cppu::supportsService(this, ServiceName);
3380 uno::Sequence< OUString > SAL_CALL SdMasterPagesAccess::getSupportedServiceNames( )
3382 return { "com.sun.star.drawing.MasterPages" };
3386 SdDocLinkTargets::SdDocLinkTargets( SdXImpressDocument& rMyModel ) noexcept
3387 : mpModel( &rMyModel )
3391 SdDocLinkTargets::~SdDocLinkTargets() noexcept
3395 // XComponent
3396 void SAL_CALL SdDocLinkTargets::dispose( )
3398 mpModel = nullptr;
3401 void SAL_CALL SdDocLinkTargets::addEventListener( const uno::Reference< lang::XEventListener >& )
3403 OSL_FAIL( "not implemented!" );
3406 void SAL_CALL SdDocLinkTargets::removeEventListener( const uno::Reference< lang::XEventListener >& )
3408 OSL_FAIL( "not implemented!" );
3411 // XNameAccess
3412 uno::Any SAL_CALL SdDocLinkTargets::getByName( const OUString& aName )
3414 ::SolarMutexGuard aGuard;
3416 if( nullptr == mpModel )
3417 throw lang::DisposedException();
3419 SdPage* pPage = FindPage( aName );
3421 if( pPage == nullptr )
3422 throw container::NoSuchElementException();
3424 uno::Any aAny;
3426 uno::Reference< beans::XPropertySet > xProps( pPage->getUnoPage(), uno::UNO_QUERY );
3427 if( xProps.is() )
3428 aAny <<= xProps;
3430 return aAny;
3433 uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getElementNames()
3435 ::SolarMutexGuard aGuard;
3437 if( nullptr == mpModel )
3438 throw lang::DisposedException();
3440 SdDrawDocument* pDoc = mpModel->GetDoc();
3441 if( pDoc == nullptr )
3443 return { };
3446 if( pDoc->GetDocumentType() == DocumentType::Draw )
3448 const sal_uInt16 nMaxPages = pDoc->GetSdPageCount( PageKind::Standard );
3449 const sal_uInt16 nMaxMasterPages = pDoc->GetMasterSdPageCount( PageKind::Standard );
3451 uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages );
3452 OUString* pStr = aSeq.getArray();
3454 sal_uInt16 nPage;
3455 // standard pages
3456 for( nPage = 0; nPage < nMaxPages; nPage++ )
3457 *pStr++ = pDoc->GetSdPage( nPage, PageKind::Standard )->GetName();
3459 // master pages
3460 for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3461 *pStr++ = pDoc->GetMasterSdPage( nPage, PageKind::Standard )->GetName();
3462 return aSeq;
3464 else
3466 const sal_uInt16 nMaxPages = pDoc->GetPageCount();
3467 const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
3469 uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages );
3470 OUString* pStr = aSeq.getArray();
3472 sal_uInt16 nPage;
3473 // standard pages
3474 for( nPage = 0; nPage < nMaxPages; nPage++ )
3475 *pStr++ = static_cast<SdPage*>(pDoc->GetPage( nPage ))->GetName();
3477 // master pages
3478 for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3479 *pStr++ = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ))->GetName();
3480 return aSeq;
3484 sal_Bool SAL_CALL SdDocLinkTargets::hasByName( const OUString& aName )
3486 ::SolarMutexGuard aGuard;
3488 if( nullptr == mpModel )
3489 throw lang::DisposedException();
3491 return FindPage( aName ) != nullptr;
3494 // container::XElementAccess
3495 uno::Type SAL_CALL SdDocLinkTargets::getElementType()
3497 return cppu::UnoType<beans::XPropertySet>::get();
3500 sal_Bool SAL_CALL SdDocLinkTargets::hasElements()
3502 ::SolarMutexGuard aGuard;
3504 if( nullptr == mpModel )
3505 throw lang::DisposedException();
3507 return mpModel->GetDoc() != nullptr;
3510 SdPage* SdDocLinkTargets::FindPage( std::u16string_view rName ) const
3512 SdDrawDocument* pDoc = mpModel->GetDoc();
3513 if( pDoc == nullptr )
3514 return nullptr;
3516 const sal_uInt16 nMaxPages = pDoc->GetPageCount();
3517 const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
3519 sal_uInt16 nPage;
3520 SdPage* pPage;
3522 const bool bDraw = pDoc->GetDocumentType() == DocumentType::Draw;
3524 // standard pages
3525 for( nPage = 0; nPage < nMaxPages; nPage++ )
3527 pPage = static_cast<SdPage*>(pDoc->GetPage( nPage ));
3528 if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
3529 return pPage;
3532 // master pages
3533 for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3535 pPage = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ));
3536 if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
3537 return pPage;
3540 return nullptr;
3543 // XServiceInfo
3544 OUString SAL_CALL SdDocLinkTargets::getImplementationName()
3546 return "SdDocLinkTargets";
3549 sal_Bool SAL_CALL SdDocLinkTargets::supportsService( const OUString& ServiceName )
3551 return cppu::supportsService( this, ServiceName );
3554 uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getSupportedServiceNames()
3556 return { "com.sun.star.document.LinkTargets" };
3559 rtl::Reference< SdXImpressDocument > SdXImpressDocument::GetModel( SdDrawDocument const & rDocument )
3561 rtl::Reference< SdXImpressDocument > xRet;
3562 ::sd::DrawDocShell* pDocShell(rDocument.GetDocSh());
3563 if( pDocShell )
3565 uno::Reference<frame::XModel> xModel(pDocShell->GetModel());
3567 xRet.set( dynamic_cast< SdXImpressDocument* >( xModel.get() ) );
3570 return xRet;
3573 void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName )
3575 rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) );
3577 if( xModel.is() )
3579 uno::Reference< uno::XInterface > xSource( static_cast<uno::XWeak*>( xModel.get() ) );
3580 css::document::EventObject aEvent( xSource, rEventName );
3581 xModel->notifyEvent(aEvent );
3585 void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName, const uno::Reference< uno::XInterface >& xSource )
3587 rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) );
3589 if( xModel.is() )
3591 css::document::EventObject aEvent( xSource, rEventName );
3592 xModel->notifyEvent(aEvent );
3596 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */