1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 
22 #include <com/sun/star/presentation/XPresentation2.hpp>
23 
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 
32 #include <com/sun/star/embed/Aspects.hpp>
33 
34 #include <comphelper/lok.hxx>
35 #include <comphelper/sequence.hxx>
36 #include <comphelper/servicehelper.hxx>
37 #include <cppuhelper/supportsservice.hxx>
38 #include <comphelper/processfactory.hxx>
39 #include <comphelper/profilezone.hxx>
40 
41 #include <sal/log.hxx>
42 #include <editeng/unofield.hxx>
43 #include <notifydocumentevent.hxx>
44 #include <unomodel.hxx>
45 #include "unopool.hxx"
46 #include <sfx2/lokhelper.hxx>
47 #include <vcl/svapp.hxx>
48 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
49 
50 #include <editeng/UnoForbiddenCharsTable.hxx>
51 #include <svx/svdoutl.hxx>
52 #include <o3tl/safeint.hxx>
53 #include <svx/UnoNamespaceMap.hxx>
54 #include <svx/svdlayer.hxx>
55 #include <svx/svdsob.hxx>
56 #include <svx/svdundo.hxx>
57 #include <svx/unoapi.hxx>
58 #include <svx/unofill.hxx>
59 #include <editeng/fontitem.hxx>
60 #include <toolkit/awt/vclxdevice.hxx>
61 #include <svx/svdpool.hxx>
62 #include <svx/svdpagv.hxx>
63 #include <svtools/unoimap.hxx>
64 #include <svtools/slidesorterbaropt.hxx>
65 #include <svx/unoshape.hxx>
66 #include <editeng/unonrule.hxx>
67 #include <editeng/eeitem.hxx>
68 #include <unotools/datetime.hxx>
69 #include <unotools/saveopt.hxx>
70 #include <xmloff/autolayout.hxx>
71 
72 // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
73 #include <svx/xmleohlp.hxx>
74 #include <svx/xmlgrhlp.hxx>
75 #include <DrawDocShell.hxx>
76 #include <ViewShellBase.hxx>
77 #include "UnoDocumentSettings.hxx"
78 
79 #include <Annotation.hxx>
80 #include <drawdoc.hxx>
81 #include <sdmod.hxx>
82 #include <sdresid.hxx>
83 #include <sdpage.hxx>
84 
85 #include <strings.hrc>
86 #include <strings.hxx>
87 #include "unolayer.hxx"
88 #include <unopage.hxx>
89 #include "unocpres.hxx"
90 #include "unoobj.hxx"
91 #include <stlpool.hxx>
92 #include "unopback.hxx"
93 #include <unokywds.hxx>
94 
95 #include <FrameView.hxx>
96 #include <ClientView.hxx>
97 #include <DrawViewShell.hxx>
98 #include <ViewShell.hxx>
99 #include <Window.hxx>
100 #include <optsitem.hxx>
101 
102 #include <vcl/pdfextoutdevdata.hxx>
103 #include <com/sun/star/presentation/AnimationSpeed.hpp>
104 #include <com/sun/star/presentation/ClickAction.hpp>
105 #include <svx/sdr/contact/viewobjectcontact.hxx>
106 #include <svx/sdr/contact/viewcontact.hxx>
107 #include <svx/sdr/contact/displayinfo.hxx>
108 
109 #include <com/sun/star/office/XAnnotation.hpp>
110 #include <com/sun/star/office/XAnnotationAccess.hpp>
111 #include <com/sun/star/office/XAnnotationEnumeration.hpp>
112 #include <com/sun/star/geometry/RealPoint2D.hpp>
113 #include <com/sun/star/util/DateTime.hpp>
114 
115 #include <drawinglayer/primitive2d/structuretagprimitive2d.hxx>
116 
117 #include <sfx2/lokcharthelper.hxx>
118 #include <tools/gen.hxx>
119 #include <tools/debug.hxx>
120 #include <tools/diagnose_ex.h>
121 #include <tools/json_writer.hxx>
122 #include <tools/UnitConversion.hxx>
123 
124 #define TWIPS_PER_PIXEL 15
125 
126 using namespace ::cppu;
127 using namespace ::com::sun::star;
128 using namespace ::sd;
129 
130 namespace {
131 
132 class SdUnoForbiddenCharsTable : public SvxUnoForbiddenCharsTable,
133                                  public SfxListener
134 {
135 public:
136     explicit SdUnoForbiddenCharsTable(SdrModel* pModel);
137     virtual ~SdUnoForbiddenCharsTable() override;
138 
139     // SfxListener
140     virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) noexcept override;
141 protected:
142     virtual void onChange() override;
143 
144 private:
145     SdrModel*   mpModel;
146 };
147 
148 }
149 
SdUnoForbiddenCharsTable(SdrModel * pModel)150 SdUnoForbiddenCharsTable::SdUnoForbiddenCharsTable( SdrModel* pModel )
151 : SvxUnoForbiddenCharsTable( pModel->GetForbiddenCharsTable() ), mpModel( pModel )
152 {
153     StartListening( *pModel );
154 }
155 
onChange()156 void SdUnoForbiddenCharsTable::onChange()
157 {
158     if( mpModel )
159     {
160         mpModel->ReformatAllTextObjects();
161     }
162 }
163 
~SdUnoForbiddenCharsTable()164 SdUnoForbiddenCharsTable::~SdUnoForbiddenCharsTable()
165 {
166     SolarMutexGuard g;
167 
168     if( mpModel )
169         EndListening( *mpModel );
170 }
171 
Notify(SfxBroadcaster &,const SfxHint & rHint)172 void SdUnoForbiddenCharsTable::Notify( SfxBroadcaster&, const SfxHint& rHint ) noexcept
173 {
174     if (rHint.GetId() != SfxHintId::ThisIsAnSdrHint)
175         return;
176     const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
177     if( SdrHintKind::ModelCleared == pSdrHint->GetKind() )
178     {
179         mpModel = nullptr;
180     }
181 }
182 
183 const sal_uInt16 WID_MODEL_LANGUAGE           =  1;
184 const sal_uInt16 WID_MODEL_TABSTOP            =  2;
185 const sal_uInt16 WID_MODEL_VISAREA            =  3;
186 const sal_uInt16 WID_MODEL_MAPUNIT            =  4;
187 const sal_uInt16 WID_MODEL_FORBCHARS          =  5;
188 const sal_uInt16 WID_MODEL_CONTFOCUS          =  6;
189 const sal_uInt16 WID_MODEL_DSGNMODE           =  7;
190 const sal_uInt16 WID_MODEL_BASICLIBS          =  8;
191 const sal_uInt16 WID_MODEL_RUNTIMEUID         =  9;
192 const sal_uInt16 WID_MODEL_BUILDID            = 10;
193 const sal_uInt16 WID_MODEL_HASVALIDSIGNATURES = 11;
194 const sal_uInt16 WID_MODEL_DIALOGLIBS         = 12;
195 const sal_uInt16 WID_MODEL_FONTS              = 13;
196 const sal_uInt16 WID_MODEL_INTEROPGRABBAG     = 14;
197 
ImplGetDrawModelPropertySet()198 static const SvxItemPropertySet* ImplGetDrawModelPropertySet()
199 {
200     // Attention: the first parameter HAS TO BE sorted!!!
201     const static SfxItemPropertyMapEntry aDrawModelPropertyMap_Impl[] =
202     {
203         { u"BuildId",                      WID_MODEL_BUILDID,            ::cppu::UnoType<OUString>::get(),                      0, 0},
204         { sUNO_Prop_CharLocale,           WID_MODEL_LANGUAGE,           ::cppu::UnoType<lang::Locale>::get(),                                  0, 0},
205         { sUNO_Prop_TabStop,              WID_MODEL_TABSTOP,            ::cppu::UnoType<sal_Int32>::get(),                                     0, 0},
206         { sUNO_Prop_VisibleArea,          WID_MODEL_VISAREA,            ::cppu::UnoType<awt::Rectangle>::get(),                                0, 0},
207         { sUNO_Prop_MapUnit,              WID_MODEL_MAPUNIT,            ::cppu::UnoType<sal_Int16>::get(),                                     beans::PropertyAttribute::READONLY, 0},
208         { sUNO_Prop_ForbiddenCharacters,  WID_MODEL_FORBCHARS,          cppu::UnoType<i18n::XForbiddenCharacters>::get(), beans::PropertyAttribute::READONLY, 0},
209         { sUNO_Prop_AutomContFocus,       WID_MODEL_CONTFOCUS,          cppu::UnoType<bool>::get(),                                                 0, 0},
210         { sUNO_Prop_ApplyFrmDsgnMode,     WID_MODEL_DSGNMODE,           cppu::UnoType<bool>::get(),                                                 0, 0},
211         { u"BasicLibraries",               WID_MODEL_BASICLIBS,          cppu::UnoType<script::XLibraryContainer>::get(),  beans::PropertyAttribute::READONLY, 0},
212         { u"DialogLibraries",              WID_MODEL_DIALOGLIBS,         cppu::UnoType<script::XLibraryContainer>::get(),  beans::PropertyAttribute::READONLY, 0},
213         { sUNO_Prop_RuntimeUID,           WID_MODEL_RUNTIMEUID,         ::cppu::UnoType<OUString>::get(),                      beans::PropertyAttribute::READONLY, 0},
214         { sUNO_Prop_HasValidSignatures,   WID_MODEL_HASVALIDSIGNATURES, ::cppu::UnoType<sal_Bool>::get(),                      beans::PropertyAttribute::READONLY, 0},
215         { u"Fonts",                        WID_MODEL_FONTS,              cppu::UnoType<uno::Sequence<uno::Any>>::get(),                     beans::PropertyAttribute::READONLY, 0},
216         { sUNO_Prop_InteropGrabBag,       WID_MODEL_INTEROPGRABBAG,     cppu::UnoType<uno::Sequence< beans::PropertyValue >>::get(),       0, 0},
217         { u"", 0, css::uno::Type(), 0, 0 }
218     };
219     static SvxItemPropertySet aDrawModelPropertySet_Impl( aDrawModelPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
220     return &aDrawModelPropertySet_Impl;
221 }
222 
223 // this ctor is used from the DocShell
SdXImpressDocument(::sd::DrawDocShell * pShell,bool bClipBoard)224 SdXImpressDocument::SdXImpressDocument(::sd::DrawDocShell* pShell, bool bClipBoard)
225 :   SfxBaseModel( pShell ),
226     mpDocShell( pShell ),
227     mpDoc( pShell ? pShell->GetDoc() : nullptr ),
228     mbDisposed(false),
229     mbImpressDoc( pShell && pShell->GetDoc() && pShell->GetDoc()->GetDocumentType() == DocumentType::Impress ),
230     mbClipBoard( bClipBoard ),
231     mpPropSet( ImplGetDrawModelPropertySet() )
232 {
233     if( mpDoc )
234     {
235         StartListening( *mpDoc );
236     }
237     else
238     {
239         OSL_FAIL("DocShell is invalid");
240     }
241 }
242 
SdXImpressDocument(SdDrawDocument * pDoc,bool bClipBoard)243 SdXImpressDocument::SdXImpressDocument(SdDrawDocument* pDoc, bool bClipBoard)
244 :   SfxBaseModel( nullptr ),
245     mpDocShell( nullptr ),
246     mpDoc( pDoc ),
247     mbDisposed(false),
248     mbImpressDoc( pDoc && pDoc->GetDocumentType() == DocumentType::Impress ),
249     mbClipBoard( bClipBoard ),
250     mpPropSet( ImplGetDrawModelPropertySet() )
251 {
252     if( mpDoc )
253     {
254         StartListening( *mpDoc );
255     }
256     else
257     {
258         OSL_FAIL("SdDrawDocument is invalid");
259     }
260 }
261 
262 /***********************************************************************
263 *                                                                      *
264 ***********************************************************************/
~SdXImpressDocument()265 SdXImpressDocument::~SdXImpressDocument() noexcept
266 {
267 }
268 
269 // XInterface
queryInterface(const uno::Type & rType)270 uno::Any SAL_CALL SdXImpressDocument::queryInterface( const uno::Type & rType )
271 {
272     uno::Any aAny;
273 
274     if (rType == cppu::UnoType<lang::XServiceInfo>::get())
275         aAny <<= uno::Reference<lang::XServiceInfo>(this);
276     else if (rType == cppu::UnoType<beans::XPropertySet>::get())
277         aAny <<= uno::Reference<beans::XPropertySet>(this);
278     else if (rType == cppu::UnoType<lang::XMultiServiceFactory>::get())
279         aAny <<= uno::Reference<lang::XMultiServiceFactory>(this);
280     else if (rType == cppu::UnoType<drawing::XDrawPageDuplicator>::get())
281         aAny <<= uno::Reference<drawing::XDrawPageDuplicator>(this);
282     else if (rType == cppu::UnoType<drawing::XLayerSupplier>::get())
283         aAny <<= uno::Reference<drawing::XLayerSupplier>(this);
284     else if (rType == cppu::UnoType<drawing::XMasterPagesSupplier>::get())
285         aAny <<= uno::Reference<drawing::XMasterPagesSupplier>(this);
286     else if (rType == cppu::UnoType<drawing::XDrawPagesSupplier>::get())
287         aAny <<= uno::Reference<drawing::XDrawPagesSupplier>(this);
288     else if (rType == cppu::UnoType<presentation::XHandoutMasterSupplier>::get())
289         aAny <<= uno::Reference<presentation::XHandoutMasterSupplier>(this);
290     else if (rType == cppu::UnoType<document::XLinkTargetSupplier>::get())
291         aAny <<= uno::Reference<document::XLinkTargetSupplier>(this);
292     else if (rType == cppu::UnoType<style::XStyleFamiliesSupplier>::get())
293         aAny <<= uno::Reference<style::XStyleFamiliesSupplier>(this);
294     else if (rType == cppu::UnoType<css::ucb::XAnyCompareFactory>::get())
295         aAny <<= uno::Reference<css::ucb::XAnyCompareFactory>(this);
296     else if (rType == cppu::UnoType<view::XRenderable>::get())
297         aAny <<= uno::Reference<view::XRenderable>(this);
298     else if (mbImpressDoc && rType == cppu::UnoType<presentation::XPresentationSupplier>::get())
299         aAny <<= uno::Reference< presentation::XPresentationSupplier >(this);
300     else if (mbImpressDoc && rType == cppu::UnoType<presentation::XCustomPresentationSupplier>::get())
301         aAny <<= uno::Reference< presentation::XCustomPresentationSupplier >(this);
302     else
303         return SfxBaseModel::queryInterface(rType);
304 
305     return aAny;
306 }
307 
acquire()308 void SAL_CALL SdXImpressDocument::acquire() noexcept
309 {
310     SfxBaseModel::acquire();
311 }
312 
release()313 void SAL_CALL SdXImpressDocument::release() noexcept
314 {
315     if (osl_atomic_decrement( &m_refCount ) != 0)
316         return;
317 
318     // restore reference count:
319     osl_atomic_increment( &m_refCount );
320     if(!mbDisposed)
321     {
322         try
323         {
324             dispose();
325         }
326         catch (const uno::RuntimeException&)
327         {
328             // don't break throw ()
329             TOOLS_WARN_EXCEPTION( "sd", "" );
330         }
331     }
332     SfxBaseModel::release();
333 }
334 
335 // XUnoTunnel
getUnoTunnelId()336 const css::uno::Sequence< sal_Int8 > & SdXImpressDocument::getUnoTunnelId() noexcept
337 {
338     static const UnoTunnelIdInit theSdXImpressDocumentUnoTunnelId;
339     return theSdXImpressDocumentUnoTunnelId.getSeq();
340 }
341 
getSomething(const css::uno::Sequence<sal_Int8> & rIdentifier)342 sal_Int64 SAL_CALL SdXImpressDocument::getSomething( const css::uno::Sequence< sal_Int8 >& rIdentifier )
343 {
344     if( isUnoTunnelId<SdXImpressDocument>(rIdentifier) )
345         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
346 
347     if( isUnoTunnelId<SdrModel>(rIdentifier) )
348         return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(mpDoc));
349 
350     return SfxBaseModel::getSomething( rIdentifier );
351 }
352 
353 // XTypeProvider
getTypes()354 uno::Sequence< uno::Type > SAL_CALL SdXImpressDocument::getTypes(  )
355 {
356     ::SolarMutexGuard aGuard;
357 
358     if( !maTypeSequence.hasElements() )
359     {
360         uno::Sequence< uno::Type > aTypes( SfxBaseModel::getTypes() );
361         aTypes = comphelper::concatSequences(aTypes,
362             uno::Sequence {
363                 cppu::UnoType<beans::XPropertySet>::get(),
364                 cppu::UnoType<lang::XServiceInfo>::get(),
365                 cppu::UnoType<lang::XMultiServiceFactory>::get(),
366                 cppu::UnoType<drawing::XDrawPageDuplicator>::get(),
367                 cppu::UnoType<drawing::XLayerSupplier>::get(),
368                 cppu::UnoType<drawing::XMasterPagesSupplier>::get(),
369                 cppu::UnoType<drawing::XDrawPagesSupplier>::get(),
370                 cppu::UnoType<document::XLinkTargetSupplier>::get(),
371                 cppu::UnoType<style::XStyleFamiliesSupplier>::get(),
372                 cppu::UnoType<css::ucb::XAnyCompareFactory>::get(),
373                 cppu::UnoType<view::XRenderable>::get() });
374         if( mbImpressDoc )
375         {
376             aTypes = comphelper::concatSequences(aTypes,
377                 uno::Sequence {
378                     cppu::UnoType<presentation::XPresentationSupplier>::get(),
379                     cppu::UnoType<presentation::XCustomPresentationSupplier>::get(),
380                     cppu::UnoType<presentation::XHandoutMasterSupplier>::get() });
381         }
382         maTypeSequence = aTypes;
383     }
384 
385     return maTypeSequence;
386 }
387 
getImplementationId()388 uno::Sequence< sal_Int8 > SAL_CALL SdXImpressDocument::getImplementationId(  )
389 {
390     return css::uno::Sequence<sal_Int8>();
391 }
392 
393 /***********************************************************************
394 *                                                                      *
395 ***********************************************************************/
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)396 void SdXImpressDocument::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
397 {
398     if( mpDoc )
399     {
400         if (rHint.GetId() == SfxHintId::ThisIsAnSdrHint)
401         {
402             const SdrHint* pSdrHint = static_cast<const SdrHint*>( &rHint );
403             if( hasEventListeners() )
404             {
405                 document::EventObject aEvent;
406                 if( SvxUnoDrawMSFactory::createEvent( mpDoc, pSdrHint, aEvent ) )
407                     notifyEvent( aEvent );
408             }
409 
410             if( pSdrHint->GetKind() == SdrHintKind::ModelCleared )
411             {
412                 if( mpDoc )
413                     EndListening( *mpDoc );
414                 mpDoc = nullptr;
415                 mpDocShell = nullptr;
416             }
417         }
418         else
419         {
420             // did our SdDrawDocument just died?
421             if(rHint.GetId() == SfxHintId::Dying)
422             {
423                 // yes, so we ask for a new one
424                 if( mpDocShell )
425                 {
426                     SdDrawDocument *pNewDoc = mpDocShell->GetDoc();
427 
428                     // is there a new one?
429                     if( pNewDoc != mpDoc )
430                     {
431                         mpDoc = pNewDoc;
432                         if(mpDoc)
433                             StartListening( *mpDoc );
434                     }
435                 }
436             }
437         }
438     }
439     SfxBaseModel::Notify( rBC, rHint );
440 }
441 
442 /******************************************************************************
443 *                                                                             *
444 ******************************************************************************/
InsertSdPage(sal_uInt16 nPage,bool bDuplicate)445 SdPage* SdXImpressDocument::InsertSdPage( sal_uInt16 nPage, bool bDuplicate )
446 {
447     sal_uInt16 nPageCount = mpDoc->GetSdPageCount( PageKind::Standard );
448     SdrLayerAdmin& rLayerAdmin = mpDoc->GetLayerAdmin();
449     SdrLayerID aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
450     SdrLayerID aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
451 
452     rtl::Reference<SdPage> pStandardPage;
453 
454     if( 0 == nPageCount )
455     {
456         // this is only used for clipboard where we only have one page
457         pStandardPage = mpDoc->AllocSdPage(false);
458 
459         Size aDefSize(21000, 29700);   // A4 portrait orientation
460         pStandardPage->SetSize( aDefSize );
461         mpDoc->InsertPage(pStandardPage.get(), 0);
462     }
463     else
464     {
465         // here we determine the page after which we should insert
466         SdPage* pPreviousStandardPage = mpDoc->GetSdPage( std::min( static_cast<sal_uInt16>(nPageCount - 1), nPage ), PageKind::Standard );
467         SdrLayerIDSet aVisibleLayers = pPreviousStandardPage->TRG_GetMasterPageVisibleLayers();
468         bool bIsPageBack = aVisibleLayers.IsSet( aBckgrnd );
469         bool bIsPageObj = aVisibleLayers.IsSet( aBckgrndObj );
470 
471         // AutoLayouts must be ready
472         mpDoc->StopWorkStartupDelay();
473 
474         /* First we create a standard page and then a notes page. It is
475            guaranteed, that after a standard page the corresponding notes page
476            follows. */
477 
478         sal_uInt16 nStandardPageNum = pPreviousStandardPage->GetPageNum() + 2;
479         SdPage* pPreviousNotesPage = static_cast<SdPage*>( mpDoc->GetPage( nStandardPageNum - 1 ) );
480         sal_uInt16 nNotesPageNum = nStandardPageNum + 1;
481 
482         /**************************************************************
483         * standard page
484         **************************************************************/
485         if( bDuplicate )
486             pStandardPage = static_cast<SdPage*>( pPreviousStandardPage->CloneSdrPage(*mpDoc).get() );
487         else
488             pStandardPage = mpDoc->AllocSdPage(false);
489 
490         pStandardPage->SetSize( pPreviousStandardPage->GetSize() );
491         pStandardPage->SetBorder( pPreviousStandardPage->GetLeftBorder(),
492                                     pPreviousStandardPage->GetUpperBorder(),
493                                     pPreviousStandardPage->GetRightBorder(),
494                                     pPreviousStandardPage->GetLowerBorder() );
495         pStandardPage->SetOrientation( pPreviousStandardPage->GetOrientation() );
496         pStandardPage->SetName(OUString());
497 
498         // insert page after current page
499         mpDoc->InsertPage(pStandardPage.get(), nStandardPageNum);
500 
501         if( !bDuplicate )
502         {
503             // use MasterPage of the current page
504             pStandardPage->TRG_SetMasterPage(pPreviousStandardPage->TRG_GetMasterPage());
505             pStandardPage->SetLayoutName( pPreviousStandardPage->GetLayoutName() );
506             pStandardPage->SetAutoLayout(AUTOLAYOUT_NONE, true );
507         }
508 
509         aBckgrnd = rLayerAdmin.GetLayerID(sUNO_LayerName_background);
510         aBckgrndObj = rLayerAdmin.GetLayerID(sUNO_LayerName_background_objects);
511         aVisibleLayers.Set(aBckgrnd, bIsPageBack);
512         aVisibleLayers.Set(aBckgrndObj, bIsPageObj);
513         pStandardPage->TRG_SetMasterPageVisibleLayers(aVisibleLayers);
514 
515         /**************************************************************
516         * notes page
517         **************************************************************/
518         rtl::Reference<SdPage> pNotesPage;
519 
520         if( bDuplicate )
521             pNotesPage = static_cast<SdPage*>( pPreviousNotesPage->CloneSdrPage(*mpDoc).get() );
522         else
523             pNotesPage = mpDoc->AllocSdPage(false);
524 
525         pNotesPage->SetSize( pPreviousNotesPage->GetSize() );
526         pNotesPage->SetBorder( pPreviousNotesPage->GetLeftBorder(),
527                                 pPreviousNotesPage->GetUpperBorder(),
528                                 pPreviousNotesPage->GetRightBorder(),
529                                 pPreviousNotesPage->GetLowerBorder() );
530         pNotesPage->SetOrientation( pPreviousNotesPage->GetOrientation() );
531         pNotesPage->SetName(OUString());
532         pNotesPage->SetPageKind(PageKind::Notes);
533 
534         // insert page after current page
535         mpDoc->InsertPage(pNotesPage.get(), nNotesPageNum);
536 
537         if( !bDuplicate )
538         {
539             // use MasterPage of the current page
540             pNotesPage->TRG_SetMasterPage(pPreviousNotesPage->TRG_GetMasterPage());
541             pNotesPage->SetLayoutName( pPreviousNotesPage->GetLayoutName() );
542             pNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true );
543         }
544     }
545 
546     SetModified();
547 
548     return pStandardPage.get();
549 }
550 
SetModified()551 void SdXImpressDocument::SetModified() noexcept
552 {
553     if( mpDoc )
554         mpDoc->SetChanged();
555 }
556 
557 // XModel
lockControllers()558 void SAL_CALL SdXImpressDocument::lockControllers(  )
559 {
560     ::SolarMutexGuard aGuard;
561 
562     if( nullptr == mpDoc )
563         throw lang::DisposedException();
564 
565     mpDoc->setLock(true);
566 }
567 
unlockControllers()568 void SAL_CALL SdXImpressDocument::unlockControllers(  )
569 {
570     ::SolarMutexGuard aGuard;
571 
572     if( nullptr == mpDoc )
573         throw lang::DisposedException();
574 
575     if( mpDoc->isLocked() )
576     {
577         mpDoc->setLock(false);
578     }
579 }
580 
hasControllersLocked()581 sal_Bool SAL_CALL SdXImpressDocument::hasControllersLocked(  )
582 {
583     ::SolarMutexGuard aGuard;
584 
585     if( nullptr == mpDoc )
586         throw lang::DisposedException();
587 
588     return mpDoc->isLocked();
589 }
590 
getViewData()591 uno::Reference < container::XIndexAccess > SAL_CALL SdXImpressDocument::getViewData()
592 {
593     ::SolarMutexGuard aGuard;
594 
595     if( nullptr == mpDoc )
596         throw lang::DisposedException();
597 
598     uno::Reference < container::XIndexAccess > xRet( SfxBaseModel::getViewData() );
599 
600     if( !xRet.is() )
601     {
602         const std::vector<std::unique_ptr<sd::FrameView>> &rList = mpDoc->GetFrameViewList();
603 
604         if( !rList.empty() )
605         {
606             xRet = document::IndexedPropertyValues::create( ::comphelper::getProcessComponentContext() );
607 
608             uno::Reference < container::XIndexContainer > xCont( xRet, uno::UNO_QUERY );
609             DBG_ASSERT( xCont.is(), "SdXImpressDocument::getViewData() failed for OLE object" );
610             if( xCont.is() )
611             {
612                 for( sal_uInt32 i = 0, n = rList.size(); i < n; i++ )
613                 {
614                     ::sd::FrameView* pFrameView = rList[ i ].get();
615 
616                     uno::Sequence< beans::PropertyValue > aSeq;
617                     pFrameView->WriteUserDataSequence( aSeq );
618                     xCont->insertByIndex( i, uno::makeAny( aSeq ) );
619                 }
620             }
621         }
622     }
623 
624     return xRet;
625 }
626 
setViewData(const uno::Reference<container::XIndexAccess> & xData)627 void SAL_CALL SdXImpressDocument::setViewData( const uno::Reference < container::XIndexAccess >& xData )
628 {
629     ::SolarMutexGuard aGuard;
630 
631     if( nullptr == mpDoc )
632         throw lang::DisposedException();
633 
634     SfxBaseModel::setViewData( xData );
635     if( !(mpDocShell && (mpDocShell->GetCreateMode() == SfxObjectCreateMode::EMBEDDED) && xData.is()) )
636         return;
637 
638     const sal_Int32 nCount = xData->getCount();
639 
640     std::vector<std::unique_ptr<sd::FrameView>> &rViews = mpDoc->GetFrameViewList();
641 
642     rViews.clear();
643 
644     uno::Sequence< beans::PropertyValue > aSeq;
645     for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ )
646     {
647         if( xData->getByIndex( nIndex ) >>= aSeq )
648         {
649             std::unique_ptr<::sd::FrameView> pFrameView(new ::sd::FrameView( mpDoc ));
650             pFrameView->ReadUserDataSequence( aSeq );
651             rViews.push_back( std::move(pFrameView) );
652         }
653     }
654 }
655 
656 // XDrawPageDuplicator
duplicate(const uno::Reference<drawing::XDrawPage> & xPage)657 uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::duplicate( const uno::Reference< drawing::XDrawPage >& xPage )
658 {
659     ::SolarMutexGuard aGuard;
660 
661     if( nullptr == mpDoc )
662         throw lang::DisposedException();
663 
664     // get pPage from xPage and determine the Id (nPos ) afterwards
665     SvxDrawPage* pSvxPage = comphelper::getUnoTunnelImplementation<SvxDrawPage>( xPage );
666     if( pSvxPage )
667     {
668         SdPage* pPage = static_cast<SdPage*>( pSvxPage->GetSdrPage() );
669         sal_uInt16 nPos = pPage->GetPageNum();
670         nPos = ( nPos - 1 ) / 2;
671         pPage = InsertSdPage( nPos, true );
672         if( pPage )
673         {
674             uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
675             return xDrawPage;
676         }
677     }
678 
679     uno::Reference< drawing::XDrawPage > xDrawPage;
680     return xDrawPage;
681 }
682 
683 // XDrawPagesSupplier
getDrawPages()684 uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getDrawPages()
685 {
686     ::SolarMutexGuard aGuard;
687 
688     if( nullptr == mpDoc )
689         throw lang::DisposedException();
690 
691     uno::Reference< drawing::XDrawPages >  xDrawPages( mxDrawPagesAccess );
692 
693     if( !xDrawPages.is() )
694     {
695         initializeDocument();
696         mxDrawPagesAccess = xDrawPages = new SdDrawPagesAccess(*this);
697     }
698 
699     return xDrawPages;
700 }
701 
702 // XMasterPagesSupplier
getMasterPages()703 uno::Reference< drawing::XDrawPages > SAL_CALL SdXImpressDocument::getMasterPages()
704 {
705     ::SolarMutexGuard aGuard;
706 
707     if( nullptr == mpDoc )
708         throw lang::DisposedException();
709 
710     uno::Reference< drawing::XDrawPages >  xMasterPages( mxMasterPagesAccess );
711 
712     if( !xMasterPages.is() )
713     {
714         if ( !hasControllersLocked() )
715             initializeDocument();
716         mxMasterPagesAccess = xMasterPages = new SdMasterPagesAccess(*this);
717     }
718 
719     return xMasterPages;
720 }
721 
722 // XLayerManagerSupplier
getLayerManager()723 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLayerManager(  )
724 {
725     ::SolarMutexGuard aGuard;
726 
727     if( nullptr == mpDoc )
728         throw lang::DisposedException();
729 
730     uno::Reference< container::XNameAccess >  xLayerManager( mxLayerManager );
731 
732     if( !xLayerManager.is() )
733         mxLayerManager = xLayerManager = new SdLayerManager(*this);
734 
735     return xLayerManager;
736 }
737 
738 // XCustomPresentationSupplier
getCustomPresentations()739 uno::Reference< container::XNameContainer > SAL_CALL SdXImpressDocument::getCustomPresentations()
740 {
741     ::SolarMutexGuard aGuard;
742 
743     if( nullptr == mpDoc )
744         throw lang::DisposedException();
745 
746     uno::Reference< container::XNameContainer >  xCustomPres( mxCustomPresentationAccess );
747 
748     if( !xCustomPres.is() )
749         mxCustomPresentationAccess = xCustomPres = new SdXCustomPresentationAccess(*this);
750 
751     return xCustomPres;
752 }
753 
754 // XPresentationSupplier
getPresentation()755 uno::Reference< presentation::XPresentation > SAL_CALL SdXImpressDocument::getPresentation()
756 {
757     ::SolarMutexGuard aGuard;
758 
759     if( nullptr == mpDoc )
760         throw lang::DisposedException();
761 
762     return mpDoc->getPresentation();
763 }
764 
765 // XHandoutMasterSupplier
getHandoutMasterPage()766 uno::Reference< drawing::XDrawPage > SAL_CALL SdXImpressDocument::getHandoutMasterPage()
767 {
768     ::SolarMutexGuard aGuard;
769 
770     if( nullptr == mpDoc )
771         throw lang::DisposedException();
772 
773     uno::Reference< drawing::XDrawPage > xPage;
774 
775     initializeDocument();
776     SdPage* pPage = mpDoc->GetMasterSdPage(0, PageKind::Handout);
777     if (pPage)
778         xPage.set(pPage->getUnoPage(), uno::UNO_QUERY);
779     return xPage;
780 }
781 
782 // XMultiServiceFactory ( SvxFmMSFactory )
783 
create(OUString const & aServiceSpecifier,OUString const & referer)784 css::uno::Reference<css::uno::XInterface> SdXImpressDocument::create(
785     OUString const & aServiceSpecifier, OUString const & referer)
786 {
787     ::SolarMutexGuard aGuard;
788 
789     if( nullptr == mpDoc )
790         throw lang::DisposedException();
791 
792     if( aServiceSpecifier == "com.sun.star.drawing.DashTable" )
793     {
794         if( !mxDashTable.is() )
795             mxDashTable = SvxUnoDashTable_createInstance( mpDoc );
796 
797         return mxDashTable;
798     }
799     if( aServiceSpecifier == "com.sun.star.drawing.GradientTable" )
800     {
801         if( !mxGradientTable.is() )
802             mxGradientTable = SvxUnoGradientTable_createInstance( mpDoc );
803 
804         return mxGradientTable;
805     }
806     if( aServiceSpecifier == "com.sun.star.drawing.HatchTable" )
807     {
808         if( !mxHatchTable.is() )
809             mxHatchTable = SvxUnoHatchTable_createInstance( mpDoc );
810 
811         return mxHatchTable;
812     }
813     if( aServiceSpecifier == "com.sun.star.drawing.BitmapTable" )
814     {
815         if( !mxBitmapTable.is() )
816             mxBitmapTable = SvxUnoBitmapTable_createInstance( mpDoc );
817 
818         return mxBitmapTable;
819     }
820     if( aServiceSpecifier == "com.sun.star.drawing.TransparencyGradientTable" )
821     {
822         if( !mxTransGradientTable.is() )
823             mxTransGradientTable = SvxUnoTransGradientTable_createInstance( mpDoc );
824 
825         return mxTransGradientTable;
826     }
827     if( aServiceSpecifier == "com.sun.star.drawing.MarkerTable" )
828     {
829         if( !mxMarkerTable.is() )
830             mxMarkerTable = SvxUnoMarkerTable_createInstance( mpDoc );
831 
832         return mxMarkerTable;
833     }
834     if( aServiceSpecifier == "com.sun.star.text.NumberingRules" )
835     {
836         return uno::Reference< uno::XInterface >( SvxCreateNumRule( mpDoc ), uno::UNO_QUERY );
837     }
838     if( aServiceSpecifier == "com.sun.star.drawing.Background" )
839     {
840         return uno::Reference< uno::XInterface >(
841             static_cast<uno::XWeak*>(new SdUnoPageBackground( mpDoc )));
842     }
843 
844     if( aServiceSpecifier == "com.sun.star.drawing.Defaults" )
845     {
846         if( !mxDrawingPool.is() )
847             mxDrawingPool = SdUnoCreatePool( mpDoc );
848 
849         return mxDrawingPool;
850 
851     }
852 
853     if ( aServiceSpecifier == sUNO_Service_ImageMapRectangleObject )
854     {
855         return SvUnoImageMapRectangleObject_createInstance( ImplGetSupportedMacroItems() );
856     }
857 
858     if ( aServiceSpecifier == sUNO_Service_ImageMapCircleObject )
859     {
860         return SvUnoImageMapCircleObject_createInstance( ImplGetSupportedMacroItems() );
861     }
862 
863     if ( aServiceSpecifier == sUNO_Service_ImageMapPolygonObject )
864     {
865         return SvUnoImageMapPolygonObject_createInstance( ImplGetSupportedMacroItems() );
866     }
867 
868     if( aServiceSpecifier == "com.sun.star.document.Settings" ||
869         ( !mbImpressDoc && ( aServiceSpecifier == "com.sun.star.drawing.DocumentSettings" ) ) ||
870         (  mbImpressDoc && ( aServiceSpecifier == "com.sun.star.presentation.DocumentSettings" ) ) )
871     {
872         return sd::DocumentSettings_createInstance( this );
873     }
874 
875     if( aServiceSpecifier == "com.sun.star.text.TextField.DateTime" ||
876         aServiceSpecifier == "com.sun.star.text.textfield.DateTime" )
877     {
878         return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::DATE ));
879     }
880 
881     if( aServiceSpecifier == "com.sun.star.presentation.TextField.Header" ||
882         aServiceSpecifier == "com.sun.star.presentation.textfield.Header" )
883     {
884         return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_HEADER ));
885     }
886 
887     if( aServiceSpecifier == "com.sun.star.presentation.TextField.Footer" ||
888         aServiceSpecifier == "com.sun.star.presentation.textfield.Footer" )
889     {
890         return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_FOOTER ));
891     }
892 
893     if( aServiceSpecifier == "com.sun.star.presentation.TextField.DateTime" ||
894         aServiceSpecifier == "com.sun.star.presentation.textfield.DateTime" )
895     {
896         return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PRESENTATION_DATE_TIME ));
897     }
898 
899     if( aServiceSpecifier == "com.sun.star.text.TextField.PageName" ||
900         aServiceSpecifier == "com.sun.star.text.textfield.PageName" )
901     {
902         return static_cast<cppu::OWeakObject *>(new SvxUnoTextField( text::textfield::Type::PAGE_NAME ));
903     }
904 
905     if (aServiceSpecifier == "com.sun.star.text.TextField.DocInfo.Custom" ||
906         aServiceSpecifier == "com.sun.star.text.textfield.DocInfo.Custom")
907     {
908         return static_cast<cppu::OWeakObject *>(new SvxUnoTextField(text::textfield::Type::DOCINFO_CUSTOM));
909     }
910 
911     if( aServiceSpecifier == "com.sun.star.xml.NamespaceMap" )
912     {
913         static sal_uInt16 aWhichIds[] = { SDRATTR_XMLATTRIBUTES, EE_CHAR_XMLATTRIBS, EE_PARA_XMLATTRIBS, 0 };
914 
915         return svx::NamespaceMap_createInstance( aWhichIds, &mpDoc->GetItemPool() );
916     }
917 
918     // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
919     if (aServiceSpecifier == "com.sun.star.document.ExportGraphicStorageHandler")
920     {
921         return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Write ));
922     }
923 
924     if (aServiceSpecifier == "com.sun.star.document.ImportGraphicStorageHandler")
925     {
926         return static_cast<cppu::OWeakObject *>(new SvXMLGraphicHelper( SvXMLGraphicHelperMode::Read ));
927     }
928 
929     if( aServiceSpecifier == "com.sun.star.document.ExportEmbeddedObjectResolver" )
930     {
931         comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
932         if( nullptr == pPersist )
933             throw lang::DisposedException();
934 
935         return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Write ));
936     }
937 
938     if( aServiceSpecifier == "com.sun.star.document.ImportEmbeddedObjectResolver" )
939     {
940         comphelper::IEmbeddedHelper* pPersist = mpDoc->GetPersist();
941         if( nullptr == pPersist )
942             throw lang::DisposedException();
943 
944         return static_cast<cppu::OWeakObject *>(new SvXMLEmbeddedObjectHelper( *pPersist, SvXMLEmbeddedObjectHelperMode::Read ));
945     }
946 
947     uno::Reference< uno::XInterface > xRet;
948 
949     if( aServiceSpecifier.startsWith( "com.sun.star.presentation.") )
950     {
951         const OUString aType( aServiceSpecifier.copy(26) );
952         rtl::Reference<SvxShape> pShape;
953 
954         sal_uInt16 nType = OBJ_TEXT;
955         // create a shape wrapper
956         if( aType.startsWith( "TitleTextShape" ) )
957         {
958             nType = OBJ_TEXT;
959         }
960         else if( aType.startsWith( "OutlinerShape" ) )
961         {
962             nType = OBJ_TEXT;
963         }
964         else if( aType.startsWith( "SubtitleShape" ) )
965         {
966             nType = OBJ_TEXT;
967         }
968         else if( aType.startsWith( "GraphicObjectShape" ) )
969         {
970             nType = OBJ_GRAF;
971         }
972         else if( aType.startsWith( "PageShape" ) )
973         {
974             nType = OBJ_PAGE;
975         }
976         else if( aType.startsWith( "OLE2Shape" ) )
977         {
978             nType = OBJ_OLE2;
979         }
980         else if( aType.startsWith( "ChartShape" ) )
981         {
982             nType = OBJ_OLE2;
983         }
984         else if( aType.startsWith( "CalcShape" ) )
985         {
986             nType = OBJ_OLE2;
987         }
988         else if( aType.startsWith( "TableShape" ) )
989         {
990             nType = OBJ_TABLE;
991         }
992         else if( aType.startsWith( "OrgChartShape" ) )
993         {
994             nType = OBJ_OLE2;
995         }
996         else if( aType.startsWith( "NotesShape" ) )
997         {
998             nType = OBJ_TEXT;
999         }
1000         else if( aType.startsWith( "HandoutShape" ) )
1001         {
1002             nType = OBJ_PAGE;
1003         }
1004         else if( aType.startsWith( "FooterShape" ) )
1005         {
1006             nType = OBJ_TEXT;
1007         }
1008         else if( aType.startsWith( "HeaderShape" ) )
1009         {
1010             nType = OBJ_TEXT;
1011         }
1012         else if( aType.startsWith( "SlideNumberShape" ) )
1013         {
1014             nType = OBJ_TEXT;
1015         }
1016         else if( aType.startsWith( "DateTimeShape" ) )
1017         {
1018             nType = OBJ_TEXT;
1019         }
1020         else if( aType.startsWith( "MediaShape" ) )
1021         {
1022             nType = OBJ_MEDIA;
1023         }
1024         else
1025         {
1026             throw lang::ServiceNotRegisteredException();
1027         }
1028 
1029         // create the API wrapper
1030         pShape = CreateSvxShapeByTypeAndInventor( nType, SdrInventor::Default, referer );
1031 
1032         // set shape type
1033         if( pShape && !mbClipBoard )
1034             pShape->SetShapeType(aServiceSpecifier);
1035 
1036         xRet = static_cast<uno::XWeak*>(pShape.get());
1037     }
1038     else if ( aServiceSpecifier == "com.sun.star.drawing.TableShape" )
1039     {
1040         rtl::Reference<SvxShape> pShape = CreateSvxShapeByTypeAndInventor( OBJ_TABLE, SdrInventor::Default, referer );
1041         if( pShape && !mbClipBoard )
1042             pShape->SetShapeType(aServiceSpecifier);
1043 
1044         xRet = static_cast<uno::XWeak*>(pShape.get());
1045     }
1046     else
1047     {
1048         xRet = SvxFmMSFactory::createInstance( aServiceSpecifier );
1049     }
1050 
1051     uno::Reference< drawing::XShape > xShape( xRet, uno::UNO_QUERY );
1052     SvxShape* pShape = xShape.is() ? comphelper::getUnoTunnelImplementation<SvxShape>(xShape) : nullptr;
1053     if (pShape)
1054     {
1055         xRet.clear();
1056         new SdXShape( pShape, this );
1057         xRet = xShape;
1058         xShape.clear();
1059     }
1060 
1061     return xRet;
1062 }
1063 
createInstance(const OUString & aServiceSpecifier)1064 uno::Reference< uno::XInterface > SAL_CALL SdXImpressDocument::createInstance( const OUString& aServiceSpecifier )
1065 {
1066     return create(aServiceSpecifier, "");
1067 }
1068 
1069 css::uno::Reference<css::uno::XInterface>
createInstanceWithArguments(OUString const & ServiceSpecifier,css::uno::Sequence<css::uno::Any> const & Arguments)1070 SdXImpressDocument::createInstanceWithArguments(
1071     OUString const & ServiceSpecifier,
1072     css::uno::Sequence<css::uno::Any> const & Arguments)
1073 {
1074     OUString arg;
1075     if ((ServiceSpecifier == "com.sun.star.drawing.GraphicObjectShape"
1076          || ServiceSpecifier == "com.sun.star.drawing.MediaShape"
1077          || ServiceSpecifier == "com.sun.star.presentation.MediaShape")
1078         && Arguments.getLength() == 1 && (Arguments[0] >>= arg))
1079     {
1080         return create(ServiceSpecifier, arg);
1081     }
1082     return SvxFmMSFactory::createInstanceWithArguments(
1083         ServiceSpecifier, Arguments);
1084 }
1085 
getAvailableServiceNames()1086 uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getAvailableServiceNames()
1087 {
1088     ::SolarMutexGuard aGuard;
1089 
1090     if( nullptr == mpDoc )
1091         throw lang::DisposedException();
1092 
1093     const uno::Sequence< OUString > aSNS_ORG( SvxFmMSFactory::getAvailableServiceNames() );
1094 
1095     uno::Sequence< OUString > aSNS( mbImpressDoc ? 36 : 19 );
1096 
1097     sal_uInt16 i(0);
1098 
1099     aSNS[i++] = "com.sun.star.drawing.DashTable";
1100     aSNS[i++] = "com.sun.star.drawing.GradientTable";
1101     aSNS[i++] = "com.sun.star.drawing.HatchTable";
1102     aSNS[i++] = "com.sun.star.drawing.BitmapTable";
1103     aSNS[i++] = "com.sun.star.drawing.TransparencyGradientTable";
1104     aSNS[i++] = "com.sun.star.drawing.MarkerTable";
1105     aSNS[i++] = "com.sun.star.text.NumberingRules";
1106     aSNS[i++] = "com.sun.star.drawing.Background";
1107     aSNS[i++] = "com.sun.star.document.Settings";
1108     aSNS[i++] = sUNO_Service_ImageMapRectangleObject;
1109     aSNS[i++] = sUNO_Service_ImageMapCircleObject;
1110     aSNS[i++] = sUNO_Service_ImageMapPolygonObject;
1111     aSNS[i++] = "com.sun.star.xml.NamespaceMap";
1112 
1113     // Support creation of GraphicStorageHandler and EmbeddedObjectResolver
1114     aSNS[i++] = "com.sun.star.document.ExportGraphicStorageHandler";
1115     aSNS[i++] = "com.sun.star.document.ImportGraphicStorageHandler";
1116     aSNS[i++] = "com.sun.star.document.ExportEmbeddedObjectResolver";
1117     aSNS[i++] = "com.sun.star.document.ImportEmbeddedObjectResolver";
1118     aSNS[i++] = "com.sun.star.drawing.TableShape";
1119 
1120     if(mbImpressDoc)
1121     {
1122         aSNS[i++] = "com.sun.star.presentation.TitleTextShape";
1123         aSNS[i++] = "com.sun.star.presentation.OutlinerShape";
1124         aSNS[i++] = "com.sun.star.presentation.SubtitleShape";
1125         aSNS[i++] = "com.sun.star.presentation.GraphicObjectShape";
1126         aSNS[i++] = "com.sun.star.presentation.ChartShape";
1127         aSNS[i++] = "com.sun.star.presentation.PageShape";
1128         aSNS[i++] = "com.sun.star.presentation.OLE2Shape";
1129         aSNS[i++] = "com.sun.star.presentation.TableShape";
1130         aSNS[i++] = "com.sun.star.presentation.OrgChartShape";
1131         aSNS[i++] = "com.sun.star.presentation.NotesShape";
1132         aSNS[i++] = "com.sun.star.presentation.HandoutShape";
1133         aSNS[i++] = "com.sun.star.presentation.DocumentSettings";
1134         aSNS[i++] = "com.sun.star.presentation.FooterShape";
1135         aSNS[i++] = "com.sun.star.presentation.HeaderShape";
1136         aSNS[i++] = "com.sun.star.presentation.SlideNumberShape";
1137         aSNS[i++] = "com.sun.star.presentation.DateTimeShape";
1138         aSNS[i++] = "com.sun.star.presentation.CalcShape";
1139         aSNS[i++] = "com.sun.star.presentation.MediaShape";
1140     }
1141     else
1142     {
1143         aSNS[i++] = "com.sun.star.drawing.DocumentSettings";
1144     }
1145 
1146     DBG_ASSERT( i == aSNS.getLength(), "Sequence overrun!" );
1147 
1148     return comphelper::concatSequences( aSNS_ORG, aSNS );
1149 }
1150 
1151 // lang::XServiceInfo
getImplementationName()1152 OUString SAL_CALL SdXImpressDocument::getImplementationName()
1153 {
1154     return "SdXImpressDocument";
1155     /* // Matching the .component information:
1156        return mbImpressDoc
1157            ? OUString("com.sun.star.comp.Draw.PresentationDocument")
1158            : OUString("com.sun.star.comp.Draw.DrawingDocument");
1159     */
1160 }
1161 
supportsService(const OUString & ServiceName)1162 sal_Bool SAL_CALL SdXImpressDocument::supportsService( const OUString& ServiceName )
1163 {
1164     return cppu::supportsService(this, ServiceName);
1165 }
1166 
getSupportedServiceNames()1167 uno::Sequence< OUString > SAL_CALL SdXImpressDocument::getSupportedServiceNames()
1168 {
1169     ::SolarMutexGuard aGuard;
1170 
1171     return { "com.sun.star.document.OfficeDocument",
1172              "com.sun.star.drawing.GenericDrawingDocument",
1173              "com.sun.star.drawing.DrawingDocumentFactory",
1174              mbImpressDoc?OUString("com.sun.star.presentation.PresentationDocument"):OUString("com.sun.star.drawing.DrawingDocument") };
1175 }
1176 
1177 // XPropertySet
getPropertySetInfo()1178 uno::Reference< beans::XPropertySetInfo > SAL_CALL SdXImpressDocument::getPropertySetInfo(  )
1179 {
1180     ::SolarMutexGuard aGuard;
1181     return mpPropSet->getPropertySetInfo();
1182 }
1183 
setPropertyValue(const OUString & aPropertyName,const uno::Any & aValue)1184 void SAL_CALL SdXImpressDocument::setPropertyValue( const OUString& aPropertyName, const uno::Any& aValue )
1185 {
1186     ::SolarMutexGuard aGuard;
1187 
1188     if( nullptr == mpDoc )
1189         throw lang::DisposedException();
1190 
1191     const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(aPropertyName);
1192 
1193     switch( pEntry ? pEntry->nWID : -1 )
1194     {
1195         case WID_MODEL_LANGUAGE:
1196         {
1197             lang::Locale aLocale;
1198             if(!(aValue >>= aLocale))
1199                 throw lang::IllegalArgumentException();
1200 
1201             mpDoc->SetLanguage( LanguageTag::convertToLanguageType(aLocale), EE_CHAR_LANGUAGE );
1202             break;
1203         }
1204         case WID_MODEL_TABSTOP:
1205         {
1206             sal_Int32 nValue = 0;
1207             if(!(aValue >>= nValue) || nValue < 0 )
1208                 throw lang::IllegalArgumentException();
1209 
1210             mpDoc->SetDefaultTabulator(static_cast<sal_uInt16>(nValue));
1211             break;
1212         }
1213         case WID_MODEL_VISAREA:
1214             {
1215                 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1216                 if( !pEmbeddedObj )
1217                     break;
1218 
1219                 awt::Rectangle aVisArea;
1220                 if( !(aValue >>= aVisArea) || (aVisArea.Width < 0) || (aVisArea.Height < 0) )
1221                     throw lang::IllegalArgumentException();
1222 
1223                 sal_Int32 nRight, nTop;
1224                 if (o3tl::checked_add(aVisArea.X, aVisArea.Width, nRight) || o3tl::checked_add(aVisArea.Y, aVisArea.Height, nTop))
1225                     throw lang::IllegalArgumentException();
1226 
1227                 pEmbeddedObj->SetVisArea(::tools::Rectangle(aVisArea.X, aVisArea.Y, nRight, nTop));
1228             }
1229             break;
1230         case WID_MODEL_CONTFOCUS:
1231             {
1232                 bool bFocus = false;
1233                 if( !(aValue >>= bFocus ) )
1234                     throw lang::IllegalArgumentException();
1235                 mpDoc->SetAutoControlFocus( bFocus );
1236             }
1237             break;
1238         case WID_MODEL_DSGNMODE:
1239             {
1240                 bool bMode = false;
1241                 if( !(aValue >>= bMode ) )
1242                     throw lang::IllegalArgumentException();
1243                 mpDoc->SetOpenInDesignMode( bMode );
1244             }
1245             break;
1246         case WID_MODEL_BUILDID:
1247             aValue >>= maBuildId;
1248             return;
1249         case WID_MODEL_MAPUNIT:
1250         case WID_MODEL_BASICLIBS:
1251         case WID_MODEL_RUNTIMEUID: // is read-only
1252         case WID_MODEL_DIALOGLIBS:
1253         case WID_MODEL_FONTS:
1254             throw beans::PropertyVetoException();
1255         case WID_MODEL_INTEROPGRABBAG:
1256             setGrabBagItem(aValue);
1257             break;
1258         default:
1259             throw beans::UnknownPropertyException( aPropertyName, static_cast<cppu::OWeakObject*>(this));
1260     }
1261 
1262     SetModified();
1263 }
1264 
getPropertyValue(const OUString & PropertyName)1265 uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& PropertyName )
1266 {
1267     ::SolarMutexGuard aGuard;
1268 
1269     uno::Any aAny;
1270     if( nullptr == mpDoc )
1271         throw lang::DisposedException();
1272 
1273     const SfxItemPropertyMapEntry* pEntry = mpPropSet->getPropertyMapEntry(PropertyName);
1274 
1275     switch( pEntry ? pEntry->nWID : -1 )
1276     {
1277         case WID_MODEL_LANGUAGE:
1278         {
1279             LanguageType eLang = mpDoc->GetLanguage( EE_CHAR_LANGUAGE );
1280             aAny <<= LanguageTag::convertToLocale( eLang);
1281             break;
1282         }
1283         case WID_MODEL_TABSTOP:
1284             aAny <<= static_cast<sal_Int32>(mpDoc->GetDefaultTabulator());
1285             break;
1286         case WID_MODEL_VISAREA:
1287             {
1288                 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1289                 if( !pEmbeddedObj )
1290                     break;
1291 
1292                 const ::tools::Rectangle& aRect = pEmbeddedObj->GetVisArea();
1293                 awt::Rectangle aVisArea( aRect.Left(), aRect.Top(), aRect.getWidth(), aRect.getHeight() );
1294                 aAny <<= aVisArea;
1295             }
1296             break;
1297         case WID_MODEL_MAPUNIT:
1298             {
1299                 SfxObjectShell* pEmbeddedObj = mpDoc->GetDocSh();
1300                 if( !pEmbeddedObj )
1301                     break;
1302 
1303                 sal_Int16 nMeasureUnit = 0;
1304                 SvxMapUnitToMeasureUnit( pEmbeddedObj->GetMapUnit(), nMeasureUnit );
1305                 aAny <<= nMeasureUnit;
1306         }
1307         break;
1308         case WID_MODEL_FORBCHARS:
1309         {
1310             aAny <<= getForbiddenCharsTable();
1311         }
1312         break;
1313         case WID_MODEL_CONTFOCUS:
1314             aAny <<= mpDoc->GetAutoControlFocus();
1315             break;
1316         case WID_MODEL_DSGNMODE:
1317             aAny <<= mpDoc->GetOpenInDesignMode();
1318             break;
1319         case WID_MODEL_BASICLIBS:
1320             aAny <<= mpDocShell->GetBasicContainer();
1321             break;
1322         case WID_MODEL_DIALOGLIBS:
1323             aAny <<= mpDocShell->GetDialogContainer();
1324             break;
1325         case WID_MODEL_RUNTIMEUID:
1326             aAny <<= getRuntimeUID();
1327             break;
1328         case WID_MODEL_BUILDID:
1329             return uno::Any( maBuildId );
1330         case WID_MODEL_HASVALIDSIGNATURES:
1331             aAny <<= hasValidSignatures();
1332             break;
1333         case WID_MODEL_FONTS:
1334             {
1335                 uno::Sequence<uno::Any> aSeq;
1336                 int nSeqIndex = 0;
1337 
1338                 sal_uInt16 const aWhichIds[] { EE_CHAR_FONTINFO, EE_CHAR_FONTINFO_CJK,
1339                                                EE_CHAR_FONTINFO_CTL };
1340 
1341                 const SfxItemPool& rPool = mpDoc->GetPool();
1342 
1343                 for(sal_uInt16 nWhichId : aWhichIds)
1344                 {
1345                     sal_uInt32 nItems = rPool.GetItemCount2( nWhichId );
1346 
1347                     aSeq.realloc( aSeq.getLength() + nItems*5 + 5 );
1348 
1349                     for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId))
1350                     {
1351                         const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem);
1352 
1353                         aSeq[nSeqIndex++] <<= pFont->GetFamilyName();
1354                         aSeq[nSeqIndex++] <<= pFont->GetStyleName();
1355                         aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily());
1356                         aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch());
1357                         aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet());
1358                     }
1359 
1360                     const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetDefaultItem( nWhichId ));
1361 
1362                     aSeq[nSeqIndex++] <<= rFont.GetFamilyName();
1363                     aSeq[nSeqIndex++] <<= rFont.GetStyleName();
1364                     aSeq[nSeqIndex++] <<= sal_Int16(rFont.GetFamily());
1365                     aSeq[nSeqIndex++] <<= sal_Int16(rFont.GetPitch());
1366                     aSeq[nSeqIndex++] <<= sal_Int16(rFont.GetCharSet());
1367 
1368                 }
1369 
1370                 aSeq.realloc( nSeqIndex );
1371                 aAny <<= aSeq;
1372                 break;
1373             }
1374         case WID_MODEL_INTEROPGRABBAG:
1375             getGrabBagItem(aAny);
1376             break;
1377         default:
1378             throw beans::UnknownPropertyException( PropertyName, static_cast<cppu::OWeakObject*>(this));
1379     }
1380 
1381     return aAny;
1382 }
1383 
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1384 void SAL_CALL SdXImpressDocument::addPropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >&  ) {}
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1385 void SAL_CALL SdXImpressDocument::removePropertyChangeListener( const OUString& , const uno::Reference< beans::XPropertyChangeListener >&  ) {}
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1386 void SAL_CALL SdXImpressDocument::addVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >&  ) {}
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1387 void SAL_CALL SdXImpressDocument::removeVetoableChangeListener( const OUString& , const uno::Reference< beans::XVetoableChangeListener >&  ) {}
1388 
1389 // XLinkTargetSupplier
getLinks()1390 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getLinks()
1391 {
1392     ::SolarMutexGuard aGuard;
1393 
1394     if( nullptr == mpDoc )
1395         throw lang::DisposedException();
1396 
1397     uno::Reference< container::XNameAccess > xLinks( mxLinks );
1398     if( !xLinks.is() )
1399         mxLinks = xLinks = new SdDocLinkTargets( *this );
1400     return xLinks;
1401 }
1402 
1403 // XStyleFamiliesSupplier
getStyleFamilies()1404 uno::Reference< container::XNameAccess > SAL_CALL SdXImpressDocument::getStyleFamilies(  )
1405 {
1406     ::SolarMutexGuard aGuard;
1407 
1408     if( nullptr == mpDoc )
1409         throw lang::DisposedException();
1410 
1411     uno::Reference< container::XNameAccess > xStyles( dynamic_cast< container::XNameAccess* >( mpDoc->GetStyleSheetPool()) );
1412     return xStyles;
1413 }
1414 
1415 // XAnyCompareFactory
createAnyCompareByName(const OUString &)1416 uno::Reference< css::ucb::XAnyCompare > SAL_CALL SdXImpressDocument::createAnyCompareByName( const OUString& )
1417 {
1418     return SvxCreateNumRuleCompare();
1419 }
1420 
1421 // XRenderable
getRendererCount(const uno::Any & rSelection,const uno::Sequence<beans::PropertyValue> &)1422 sal_Int32 SAL_CALL SdXImpressDocument::getRendererCount( const uno::Any& rSelection,
1423                                                          const uno::Sequence< beans::PropertyValue >&  )
1424 {
1425     ::SolarMutexGuard aGuard;
1426     sal_Int32   nRet = 0;
1427 
1428     if( nullptr == mpDoc )
1429         throw lang::DisposedException();
1430 
1431     if (mpDocShell)
1432     {
1433         uno::Reference< frame::XModel > xModel;
1434 
1435         rSelection >>= xModel;
1436 
1437         if( xModel == mpDocShell->GetModel() )
1438             nRet = mpDoc->GetSdPageCount( PageKind::Standard );
1439         else
1440         {
1441             uno::Reference< drawing::XShapes > xShapes;
1442 
1443             rSelection >>= xShapes;
1444 
1445             if( xShapes.is() && xShapes->getCount() )
1446                 nRet = 1;
1447         }
1448     }
1449     return nRet;
1450 }
1451 
getRenderer(sal_Int32,const uno::Any &,const uno::Sequence<beans::PropertyValue> & rxOptions)1452 uno::Sequence< beans::PropertyValue > SAL_CALL SdXImpressDocument::getRenderer( sal_Int32 , const uno::Any& ,
1453                                                                                 const uno::Sequence< beans::PropertyValue >& rxOptions )
1454 {
1455     ::SolarMutexGuard aGuard;
1456 
1457     if( nullptr == mpDoc )
1458         throw lang::DisposedException();
1459 
1460     bool bExportNotesPages = false;
1461     for( const auto& rOption : rxOptions )
1462     {
1463         if ( rOption.Name == "ExportNotesPages" )
1464             rOption.Value >>= bExportNotesPages;
1465     }
1466     uno::Sequence< beans::PropertyValue > aRenderer;
1467     if (mpDocShell)
1468     {
1469         awt::Size aPageSize;
1470         if ( bExportNotesPages )
1471         {
1472             Size aNotesPageSize = mpDoc->GetSdPage( 0, PageKind::Notes )->GetSize();
1473             aPageSize = awt::Size( aNotesPageSize.Width(), aNotesPageSize.Height() );
1474         }
1475         else
1476         {
1477             const ::tools::Rectangle aVisArea( mpDocShell->GetVisArea( embed::Aspects::MSOLE_DOCPRINT ) );
1478             aPageSize = awt::Size( aVisArea.GetWidth(), aVisArea.GetHeight() );
1479         }
1480         aRenderer.realloc( 1 );
1481 
1482         aRenderer[ 0 ].Name = "PageSize" ;
1483         aRenderer[ 0 ].Value <<= aPageSize;
1484     }
1485     return aRenderer;
1486 }
1487 
1488 namespace {
1489 
1490 class ImplRenderPaintProc : public sdr::contact::ViewObjectContactRedirector
1491 {
1492     const SdrLayerAdmin&    rLayerAdmin;
1493     SdrPageView*            pSdrPageView;
1494     vcl::PDFExtOutDevData*  pPDFExtOutDevData;
1495 
1496     vcl::PDFWriter::StructElement ImplBegStructureTag( SdrObject& rObject );
1497 
1498 public:
1499     bool IsVisible  ( const SdrObject* pObj ) const;
1500     bool IsPrintable( const SdrObject* pObj ) const;
1501 
1502     ImplRenderPaintProc( const SdrLayerAdmin& rLA, SdrPageView* pView, vcl::PDFExtOutDevData* pData );
1503 
1504     // all default implementations just call the same methods at the original. To do something
1505     // different, override the method and at least do what the method does.
1506     virtual drawinglayer::primitive2d::Primitive2DContainer createRedirectedPrimitive2DSequence(
1507         const sdr::contact::ViewObjectContact& rOriginal,
1508         const sdr::contact::DisplayInfo& rDisplayInfo) override;
1509 };
1510 
1511 }
1512 
ImplRenderPaintProc(const SdrLayerAdmin & rLA,SdrPageView * pView,vcl::PDFExtOutDevData * pData)1513 ImplRenderPaintProc::ImplRenderPaintProc( const SdrLayerAdmin& rLA, SdrPageView* pView, vcl::PDFExtOutDevData* pData )
1514 :   ViewObjectContactRedirector(),
1515     rLayerAdmin         ( rLA ),
1516     pSdrPageView        ( pView ),
1517     pPDFExtOutDevData   ( pData )
1518 {
1519 }
1520 
ImplPDFGetBookmarkPage(const OUString & rBookmark,SdDrawDocument const & rDoc)1521 static sal_Int32 ImplPDFGetBookmarkPage( const OUString& rBookmark, SdDrawDocument const & rDoc )
1522 {
1523     sal_Int32 nPage = -1;
1524 
1525     OUString aBookmark( rBookmark );
1526 
1527     if( rBookmark.startsWith("#") )
1528         aBookmark = rBookmark.copy( 1 );
1529 
1530     // is the bookmark a page ?
1531     bool        bIsMasterPage;
1532     sal_uInt16  nPgNum = rDoc.GetPageByName( aBookmark, bIsMasterPage );
1533 
1534     if ( nPgNum == SDRPAGE_NOTFOUND )
1535     {
1536         // is the bookmark an object ?
1537         SdrObject* pObj = rDoc.GetObj( aBookmark );
1538         if (pObj)
1539             nPgNum = pObj->getSdrPageFromSdrObject()->GetPageNum();
1540     }
1541     if ( nPgNum != SDRPAGE_NOTFOUND )
1542         nPage = ( nPgNum - 1 ) / 2;
1543     return nPage;
1544 }
1545 
ImplPDFExportComments(const uno::Reference<drawing::XDrawPage> & xPage,vcl::PDFExtOutDevData & rPDFExtOutDevData)1546 static void ImplPDFExportComments( const uno::Reference< drawing::XDrawPage >& xPage, vcl::PDFExtOutDevData& rPDFExtOutDevData )
1547 {
1548     try
1549     {
1550         uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xPage, uno::UNO_QUERY_THROW );
1551         uno::Reference< office::XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
1552 
1553         while( xAnnotationEnumeration->hasMoreElements() )
1554         {
1555             uno::Reference< office::XAnnotation > xAnnotation( xAnnotationEnumeration->nextElement() );
1556 
1557             geometry::RealPoint2D aRealPoint2D( xAnnotation->getPosition() );
1558             uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
1559 
1560             vcl::PDFNote aNote;
1561             aNote.Title = xAnnotation->getAuthor();
1562             aNote.Contents = xText->getString();
1563             aNote.maModificationDate = xAnnotation->getDateTime();
1564 
1565             rPDFExtOutDevData.CreateNote( ::tools::Rectangle( Point( static_cast< ::tools::Long >( aRealPoint2D.X * 100 ),
1566                 static_cast< ::tools::Long >( aRealPoint2D.Y * 100 ) ), Size( 1000, 1000 ) ), aNote );
1567         }
1568     }
1569     catch (const uno::Exception&)
1570     {
1571     }
1572 }
1573 
ImplPDFExportShapeInteraction(const uno::Reference<drawing::XShape> & xShape,SdDrawDocument & rDoc,vcl::PDFExtOutDevData & rPDFExtOutDevData)1574 static void ImplPDFExportShapeInteraction( const uno::Reference< drawing::XShape >& xShape, SdDrawDocument& rDoc, vcl::PDFExtOutDevData& rPDFExtOutDevData )
1575 {
1576     if ( xShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1577     {
1578         uno::Reference< container::XIndexAccess > xIndexAccess( xShape, uno::UNO_QUERY );
1579         if ( xIndexAccess.is() )
1580         {
1581             sal_Int32 i, nCount = xIndexAccess->getCount();
1582             for ( i = 0; i < nCount; i++ )
1583             {
1584                 uno::Reference< drawing::XShape > xSubShape( xIndexAccess->getByIndex( i ), uno::UNO_QUERY );
1585                 if ( xSubShape.is() )
1586                     ImplPDFExportShapeInteraction( xSubShape, rDoc, rPDFExtOutDevData );
1587             }
1588         }
1589     }
1590     else
1591     {
1592         uno::Reference< beans::XPropertySet > xShapePropSet( xShape, uno::UNO_QUERY );
1593         if( xShapePropSet.is() )
1594         {
1595             Size        aPageSize( rDoc.GetSdPage( 0, PageKind::Standard )->GetSize() );
1596             Point aPoint( 0, 0 );
1597             ::tools::Rectangle   aPageRect( aPoint, aPageSize );
1598 
1599             awt::Point  aShapePos( xShape->getPosition() );
1600             awt::Size   aShapeSize( xShape->getSize() );
1601             ::tools::Rectangle   aLinkRect( Point( aShapePos.X, aShapePos.Y ), Size( aShapeSize.Width, aShapeSize.Height ) );
1602 
1603             // Handle linked videos.
1604             if (xShape->getShapeType() == "com.sun.star.drawing.MediaShape" || xShape->getShapeType() == "com.sun.star.presentation.MediaShape")
1605             {
1606                 OUString aMediaURL;
1607                 xShapePropSet->getPropertyValue("MediaURL") >>= aMediaURL;
1608                 if (!aMediaURL.isEmpty())
1609                 {
1610                     sal_Int32 nScreenId = rPDFExtOutDevData.CreateScreen(aLinkRect, rPDFExtOutDevData.GetCurrentPageNumber());
1611                     if (aMediaURL.startsWith("vnd.sun.star.Package:"))
1612                     {
1613                         OUString aTempFileURL;
1614                         xShapePropSet->getPropertyValue("PrivateTempFileURL") >>= aTempFileURL;
1615                         rPDFExtOutDevData.SetScreenStream(nScreenId, aTempFileURL);
1616                     }
1617                     else
1618                         rPDFExtOutDevData.SetScreenURL(nScreenId, aMediaURL);
1619                 }
1620             }
1621 
1622             presentation::ClickAction eCa;
1623             uno::Any aAny( xShapePropSet->getPropertyValue( "OnClick" ) );
1624             if ( aAny >>= eCa )
1625             {
1626                 switch ( eCa )
1627                 {
1628                     case presentation::ClickAction_LASTPAGE :
1629                     {
1630                         sal_Int32 nCount = rDoc.GetSdPageCount( PageKind::Standard );
1631                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nCount - 1, vcl::PDFWriter::DestAreaType::FitRectangle );
1632                         sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1633                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1634                     }
1635                     break;
1636                     case presentation::ClickAction_FIRSTPAGE :
1637                     {
1638                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, 0, vcl::PDFWriter::DestAreaType::FitRectangle );
1639                         sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1640                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1641                     }
1642                     break;
1643                     case presentation::ClickAction_PREVPAGE :
1644                     {
1645                         sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber();
1646                         if ( nDestPage )
1647                             nDestPage--;
1648                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1649                         sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1650                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1651                     }
1652                     break;
1653                     case presentation::ClickAction_NEXTPAGE :
1654                     {
1655                         sal_Int32 nDestPage = rPDFExtOutDevData.GetCurrentPageNumber() + 1;
1656                         sal_Int32 nLastPage = rDoc.GetSdPageCount( PageKind::Standard ) - 1;
1657                         if ( nDestPage > nLastPage )
1658                             nDestPage = nLastPage;
1659                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nDestPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1660                         sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1661                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1662                     }
1663                     break;
1664 
1665                     case presentation::ClickAction_PROGRAM :
1666                     case presentation::ClickAction_BOOKMARK :
1667                     case presentation::ClickAction_DOCUMENT :
1668                     {
1669                         OUString aBookmark;
1670                         xShapePropSet->getPropertyValue( "Bookmark" ) >>= aBookmark;
1671                         if( !aBookmark.isEmpty() )
1672                         {
1673                             switch( eCa )
1674                             {
1675                                 case presentation::ClickAction_DOCUMENT :
1676                                 case presentation::ClickAction_PROGRAM :
1677                                 {
1678                                     sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1679                                     rPDFExtOutDevData.SetLinkURL( nLinkId, aBookmark );
1680                                 }
1681                                 break;
1682                                 case presentation::ClickAction_BOOKMARK :
1683                                 {
1684                                     sal_Int32 nPage = ImplPDFGetBookmarkPage( aBookmark, rDoc );
1685                                     if ( nPage != -1 )
1686                                     {
1687                                         sal_Int32 nDestId = rPDFExtOutDevData.CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle );
1688                                         sal_Int32 nLinkId = rPDFExtOutDevData.CreateLink( aLinkRect );
1689                                         rPDFExtOutDevData.SetLinkDest( nLinkId, nDestId );
1690                                     }
1691                                 }
1692                                 break;
1693                                 default:
1694                                     break;
1695                             }
1696                         }
1697                     }
1698                     break;
1699 
1700                     case presentation::ClickAction_STOPPRESENTATION :
1701                     case presentation::ClickAction_SOUND :
1702                     case presentation::ClickAction_INVISIBLE :
1703                     case presentation::ClickAction_VERB :
1704                     case presentation::ClickAction_VANISH :
1705                     case presentation::ClickAction_MACRO :
1706                     default :
1707                     break;
1708                 }
1709             }
1710         }
1711     }
1712 }
1713 
ImplBegStructureTag(SdrObject & rObject)1714 vcl::PDFWriter::StructElement ImplRenderPaintProc::ImplBegStructureTag( SdrObject& rObject )
1715 {
1716     vcl::PDFWriter::StructElement eElement(vcl::PDFWriter::NonStructElement);
1717 
1718     if ( pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportTaggedPDF() )
1719     {
1720         SdrInventor nInventor   = rObject.GetObjInventor();
1721         sal_uInt16  nIdentifier = rObject.GetObjIdentifier();
1722         bool        bIsTextObj  = dynamic_cast< const SdrTextObj *>( &rObject ) !=  nullptr;
1723 
1724         if ( nInventor == SdrInventor::Default )
1725         {
1726             if ( nIdentifier == OBJ_GRUP )
1727                 eElement = vcl::PDFWriter::Section;
1728             else if ( nIdentifier == OBJ_TITLETEXT )
1729                 eElement = vcl::PDFWriter::Heading;
1730             else if ( nIdentifier == OBJ_OUTLINETEXT )
1731                 eElement = vcl::PDFWriter::Division;
1732             else if ( !bIsTextObj || !static_cast<SdrTextObj&>(rObject).HasText() )
1733                 eElement = vcl::PDFWriter::Figure;
1734         }
1735     }
1736 
1737     return eElement;
1738 }
1739 
createRedirectedPrimitive2DSequence(const sdr::contact::ViewObjectContact & rOriginal,const sdr::contact::DisplayInfo & rDisplayInfo)1740 drawinglayer::primitive2d::Primitive2DContainer ImplRenderPaintProc::createRedirectedPrimitive2DSequence(
1741     const sdr::contact::ViewObjectContact& rOriginal,
1742     const sdr::contact::DisplayInfo& rDisplayInfo)
1743 {
1744     SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
1745 
1746     if(pObject)
1747     {
1748         drawinglayer::primitive2d::Primitive2DContainer xRetval;
1749 
1750         if(pObject->getSdrPageFromSdrObject())
1751         {
1752             if(pObject->getSdrPageFromSdrObject()->checkVisibility(rOriginal, rDisplayInfo, false))
1753             {
1754                 if(IsVisible(pObject) && IsPrintable(pObject))
1755                 {
1756                     const vcl::PDFWriter::StructElement eElement(ImplBegStructureTag( *pObject ));
1757                     const bool bTagUsed(vcl::PDFWriter::NonStructElement != eElement);
1758 
1759                     xRetval = sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
1760 
1761                     if(!xRetval.empty() && bTagUsed)
1762                     {
1763                         // embed Primitive2DSequence in a structure tag element for
1764                         // exactly this purpose (StructureTagPrimitive2D)
1765 
1766                         const SdrPage* pSdrPage(pObject->getSdrPageFromSdrObject());
1767                         const bool bBackground(nullptr != pSdrPage && pSdrPage->IsMasterPage());
1768                         const bool bImage(pObject->GetObjIdentifier() == OBJ_GRAF);
1769 
1770                         const drawinglayer::primitive2d::Primitive2DReference xReference(
1771                             new drawinglayer::primitive2d::StructureTagPrimitive2D(
1772                                 eElement,
1773                                 bBackground,
1774                                 bImage,
1775                                 xRetval));
1776 
1777                         xRetval = drawinglayer::primitive2d::Primitive2DContainer { xReference };
1778                     }
1779                 }
1780             }
1781         }
1782 
1783         return xRetval;
1784     }
1785     else
1786     {
1787         // not an object, maybe a page
1788         return sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
1789     }
1790 }
1791 
IsVisible(const SdrObject * pObj) const1792 bool ImplRenderPaintProc::IsVisible( const SdrObject* pObj ) const
1793 {
1794     bool bVisible = true;
1795     SdrLayerID nLayerId = pObj->GetLayer();
1796     if( pSdrPageView )
1797     {
1798         const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
1799         if ( pSdrLayer )
1800         {
1801             const OUString& aLayerName = pSdrLayer->GetName();
1802             bVisible = pSdrPageView->IsLayerVisible( aLayerName );
1803         }
1804     }
1805     return bVisible;
1806 }
IsPrintable(const SdrObject * pObj) const1807 bool ImplRenderPaintProc::IsPrintable( const SdrObject* pObj ) const
1808 {
1809     bool bPrintable = true;
1810     SdrLayerID nLayerId = pObj->GetLayer();
1811     if( pSdrPageView )
1812     {
1813         const SdrLayer* pSdrLayer = rLayerAdmin.GetLayerPerID( nLayerId );
1814         if ( pSdrLayer )
1815         {
1816             const OUString& aLayerName = pSdrLayer->GetName();
1817             bPrintable = pSdrPageView->IsLayerPrintable( aLayerName );
1818         }
1819     }
1820     return bPrintable;
1821 
1822 }
1823 
1824 namespace
1825 {
CalcOutputPageNum(vcl::PDFExtOutDevData const * pPDFExtOutDevData,SdDrawDocument const * pDoc,sal_Int16 nPageNumber)1826     sal_Int16 CalcOutputPageNum(vcl::PDFExtOutDevData const * pPDFExtOutDevData, SdDrawDocument const *pDoc, sal_Int16 nPageNumber)
1827     {
1828         //export all pages, simple one to one case
1829         if (pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides())
1830             return nPageNumber-1;
1831         //check all preceding pages, and only count non-hidden ones
1832         sal_Int16 nRet = 0;
1833         for (sal_Int16 i = 0; i < nPageNumber-1; ++i)
1834         {
1835            if (!pDoc->GetSdPage(i, PageKind::Standard)->IsExcluded())
1836                 ++nRet;
1837         }
1838         return nRet;
1839     }
1840 }
1841 
render(sal_Int32 nRenderer,const uno::Any & rSelection,const uno::Sequence<beans::PropertyValue> & rxOptions)1842 void SAL_CALL SdXImpressDocument::render( sal_Int32 nRenderer, const uno::Any& rSelection,
1843                                           const uno::Sequence< beans::PropertyValue >& rxOptions )
1844 {
1845     ::SolarMutexGuard aGuard;
1846 
1847     if( nullptr == mpDoc )
1848         throw lang::DisposedException();
1849 
1850     if (!mpDocShell)
1851         return;
1852 
1853     uno::Reference< awt::XDevice >  xRenderDevice;
1854     const sal_Int32                 nPageNumber = nRenderer + 1;
1855     PageKind                        ePageKind = PageKind::Standard;
1856     bool                        bExportNotesPages = false;
1857 
1858     for( const auto& rOption : rxOptions )
1859     {
1860         if ( rOption.Name == "RenderDevice" )
1861             rOption.Value >>= xRenderDevice;
1862         else if ( rOption.Name == "ExportNotesPages" )
1863         {
1864             rOption.Value >>= bExportNotesPages;
1865             if ( bExportNotesPages )
1866                 ePageKind = PageKind::Notes;
1867         }
1868     }
1869 
1870     if( !(xRenderDevice.is() && nPageNumber && ( nPageNumber <= mpDoc->GetSdPageCount( ePageKind ) )) )
1871         return;
1872 
1873     VCLXDevice* pDevice = comphelper::getUnoTunnelImplementation<VCLXDevice>( xRenderDevice );
1874     VclPtr< OutputDevice> pOut = pDevice ? pDevice->GetOutputDevice() : VclPtr< OutputDevice >();
1875 
1876     if( !pOut )
1877         return;
1878 
1879     vcl::PDFExtOutDevData* pPDFExtOutDevData = dynamic_cast<vcl::PDFExtOutDevData* >( pOut->GetExtOutDevData() );
1880 
1881     if ( mpDoc->GetSdPage(static_cast<sal_Int16>(nPageNumber)-1, PageKind::Standard)->IsExcluded() &&
1882         !(pPDFExtOutDevData && pPDFExtOutDevData->GetIsExportHiddenSlides()) )
1883         return;
1884 
1885     ::sd::ClientView aView( mpDocShell, pOut );
1886     ::tools::Rectangle aVisArea( Point(), mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind )->GetSize() );
1887     vcl::Region                       aRegion( aVisArea );
1888 
1889     ::sd::ViewShell* pOldViewSh = mpDocShell->GetViewShell();
1890     ::sd::View* pOldSdView = pOldViewSh ? pOldViewSh->GetView() : nullptr;
1891 
1892     if  ( pOldSdView )
1893         pOldSdView->SdrEndTextEdit();
1894 
1895     aView.SetHlplVisible( false );
1896     aView.SetGridVisible( false );
1897     aView.SetBordVisible( false );
1898     aView.SetPageVisible( false );
1899     aView.SetGlueVisible( false );
1900 
1901     pOut->SetMapMode(MapMode(MapUnit::Map100thMM));
1902     pOut->IntersectClipRegion( aVisArea );
1903 
1904     uno::Reference< frame::XModel > xModel;
1905     rSelection >>= xModel;
1906 
1907     if( xModel == mpDocShell->GetModel() )
1908     {
1909         aView.ShowSdrPage( mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1, ePageKind ));
1910         SdrPageView* pPV = aView.GetSdrPageView();
1911 
1912         if( pOldSdView )
1913         {
1914             SdrPageView* pOldPV = pOldSdView->GetSdrPageView();
1915             if( pPV && pOldPV )
1916             {
1917                 pPV->SetVisibleLayers( pOldPV->GetVisibleLayers() );
1918                 pPV->SetPrintableLayers( pOldPV->GetPrintableLayers() );
1919             }
1920         }
1921 
1922         ImplRenderPaintProc aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
1923             pPV, pPDFExtOutDevData );
1924 
1925         // background color for outliner :o
1926         SdPage* pPage = pPV ? static_cast<SdPage*>(pPV->GetPage()) : nullptr;
1927         if( pPage )
1928         {
1929             SdrOutliner& rOutl = mpDoc->GetDrawOutliner();
1930             bool bScreenDisplay(true);
1931 
1932             // #i75566# printing; suppress AutoColor BackgroundColor generation
1933             // for visibility reasons by giving GetPageBackgroundColor()
1934             // the needed hint
1935             // #i75566# PDF export; suppress AutoColor BackgroundColor generation (see printing)
1936             if (pOut && ((OUTDEV_PRINTER == pOut->GetOutDevType())
1937                     || (OUTDEV_PDF == pOut->GetOutDevType())))
1938                 bScreenDisplay = false;
1939 
1940             // #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
1941             // hint value if screen display. Only then the AutoColor mechanisms shall be applied
1942             rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor( pPV, bScreenDisplay ) );
1943         }
1944         aView.SdrPaintView::CompleteRedraw( pOut, aRegion, &aImplRenderPaintProc );
1945 
1946         if ( pPDFExtOutDevData && pPage )
1947         {
1948             try
1949             {
1950                 uno::Any aAny;
1951                 uno::Reference< drawing::XDrawPage > xPage( uno::Reference< drawing::XDrawPage >::query( pPage->getUnoPage() ) );
1952                 if ( xPage.is() )
1953                 {
1954                     if ( pPDFExtOutDevData->GetIsExportNotes() )
1955                         ImplPDFExportComments( xPage, *pPDFExtOutDevData );
1956                     uno::Reference< beans::XPropertySet > xPagePropSet( xPage, uno::UNO_QUERY );
1957                     if( xPagePropSet.is() )
1958                     {
1959                         // exporting object interactions to pdf
1960 
1961                         // if necessary, the master page interactions will be exported first
1962                         bool bIsBackgroundObjectsVisible = false;   // #i39428# IsBackgroundObjectsVisible not available for Draw
1963                         if ( mbImpressDoc && xPagePropSet->getPropertySetInfo()->hasPropertyByName( "IsBackgroundObjectsVisible" ) )
1964                             xPagePropSet->getPropertyValue( "IsBackgroundObjectsVisible" ) >>= bIsBackgroundObjectsVisible;
1965                         if ( bIsBackgroundObjectsVisible && !pPDFExtOutDevData->GetIsExportNotesPages() )
1966                         {
1967                             uno::Reference< drawing::XMasterPageTarget > xMasterPageTarget( xPage, uno::UNO_QUERY );
1968                             if ( xMasterPageTarget.is() )
1969                             {
1970                                 uno::Reference< drawing::XDrawPage > xMasterPage = xMasterPageTarget->getMasterPage();
1971                                 if ( xMasterPage.is() )
1972                                 {
1973                                     sal_Int32 i, nCount = xMasterPage->getCount();
1974                                     for ( i = 0; i < nCount; i++ )
1975                                     {
1976                                         aAny = xMasterPage->getByIndex( i );
1977                                         uno::Reference< drawing::XShape > xShape;
1978                                         if ( aAny >>= xShape )
1979                                             ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
1980                                     }
1981                                 }
1982                             }
1983                         }
1984 
1985                         // exporting slide page object interactions
1986                         sal_Int32 i, nCount = xPage->getCount();
1987                         for ( i = 0; i < nCount; i++ )
1988                         {
1989                             aAny = xPage->getByIndex( i );
1990                             uno::Reference< drawing::XShape > xShape;
1991                             if ( aAny >>= xShape )
1992                                 ImplPDFExportShapeInteraction( xShape, *mpDoc, *pPDFExtOutDevData );
1993                         }
1994 
1995                         // exporting transition effects to pdf
1996                         if ( mbImpressDoc && !pPDFExtOutDevData->GetIsExportNotesPages() && pPDFExtOutDevData->GetIsExportTransitionEffects() )
1997                         {
1998                             static const OUStringLiteral sEffect( u"Effect" );
1999                             static const OUStringLiteral sSpeed ( u"Speed" );
2000                             sal_Int32 nTime = 800;
2001                             presentation::AnimationSpeed aAs;
2002                             if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
2003                             {
2004                                 aAny = xPagePropSet->getPropertyValue( sSpeed );
2005                                 if ( aAny >>= aAs )
2006                                 {
2007                                     switch( aAs )
2008                                     {
2009                                         case presentation::AnimationSpeed_SLOW : nTime = 1500; break;
2010                                         case presentation::AnimationSpeed_FAST : nTime = 300; break;
2011                                         default:
2012                                         case presentation::AnimationSpeed_MEDIUM : nTime = 800;
2013                                     }
2014                                 }
2015                             }
2016                             presentation::FadeEffect eFe;
2017                             vcl::PDFWriter::PageTransition eType = vcl::PDFWriter::PageTransition::Regular;
2018                             if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) )
2019                             {
2020                                 aAny = xPagePropSet->getPropertyValue( sEffect );
2021                                 if ( aAny >>= eFe )
2022                                 {
2023                                     switch( eFe )
2024                                     {
2025                                         case presentation::FadeEffect_HORIZONTAL_LINES :
2026                                         case presentation::FadeEffect_HORIZONTAL_CHECKERBOARD :
2027                                         case presentation::FadeEffect_HORIZONTAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsHorizontal; break;
2028 
2029                                         case presentation::FadeEffect_VERTICAL_LINES :
2030                                         case presentation::FadeEffect_VERTICAL_CHECKERBOARD :
2031                                         case presentation::FadeEffect_VERTICAL_STRIPES : eType = vcl::PDFWriter::PageTransition::BlindsVertical; break;
2032 
2033                                         case presentation::FadeEffect_UNCOVER_TO_RIGHT :
2034                                         case presentation::FadeEffect_UNCOVER_TO_UPPERRIGHT :
2035                                         case presentation::FadeEffect_ROLL_FROM_LEFT :
2036                                         case presentation::FadeEffect_FADE_FROM_UPPERLEFT :
2037                                         case presentation::FadeEffect_MOVE_FROM_UPPERLEFT :
2038                                         case presentation::FadeEffect_FADE_FROM_LEFT :
2039                                         case presentation::FadeEffect_MOVE_FROM_LEFT : eType = vcl::PDFWriter::PageTransition::WipeLeftToRight; break;
2040 
2041                                         case presentation::FadeEffect_UNCOVER_TO_BOTTOM :
2042                                         case presentation::FadeEffect_UNCOVER_TO_LOWERRIGHT :
2043                                         case presentation::FadeEffect_ROLL_FROM_TOP :
2044                                         case presentation::FadeEffect_FADE_FROM_UPPERRIGHT :
2045                                         case presentation::FadeEffect_MOVE_FROM_UPPERRIGHT :
2046                                         case presentation::FadeEffect_FADE_FROM_TOP :
2047                                         case presentation::FadeEffect_MOVE_FROM_TOP : eType = vcl::PDFWriter::PageTransition::WipeTopToBottom; break;
2048 
2049                                         case presentation::FadeEffect_UNCOVER_TO_LEFT :
2050                                         case presentation::FadeEffect_UNCOVER_TO_LOWERLEFT :
2051                                         case presentation::FadeEffect_ROLL_FROM_RIGHT :
2052 
2053                                         case presentation::FadeEffect_FADE_FROM_LOWERRIGHT :
2054                                         case presentation::FadeEffect_MOVE_FROM_LOWERRIGHT :
2055                                         case presentation::FadeEffect_FADE_FROM_RIGHT :
2056                                         case presentation::FadeEffect_MOVE_FROM_RIGHT : eType = vcl::PDFWriter::PageTransition::WipeRightToLeft; break;
2057 
2058                                         case presentation::FadeEffect_UNCOVER_TO_TOP :
2059                                         case presentation::FadeEffect_UNCOVER_TO_UPPERLEFT :
2060                                         case presentation::FadeEffect_ROLL_FROM_BOTTOM :
2061                                         case presentation::FadeEffect_FADE_FROM_LOWERLEFT :
2062                                         case presentation::FadeEffect_MOVE_FROM_LOWERLEFT :
2063                                         case presentation::FadeEffect_FADE_FROM_BOTTOM :
2064                                         case presentation::FadeEffect_MOVE_FROM_BOTTOM : eType = vcl::PDFWriter::PageTransition::WipeBottomToTop; break;
2065 
2066                                         case presentation::FadeEffect_OPEN_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalInward; break;
2067                                         case presentation::FadeEffect_CLOSE_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitHorizontalOutward; break;
2068 
2069                                         case presentation::FadeEffect_OPEN_HORIZONTAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalInward; break;
2070                                         case presentation::FadeEffect_CLOSE_VERTICAL : eType = vcl::PDFWriter::PageTransition::SplitVerticalOutward; break;
2071 
2072                                         case presentation::FadeEffect_FADE_TO_CENTER : eType = vcl::PDFWriter::PageTransition::BoxInward; break;
2073                                         case presentation::FadeEffect_FADE_FROM_CENTER : eType = vcl::PDFWriter::PageTransition::BoxOutward; break;
2074 
2075                                         case presentation::FadeEffect_NONE : eType = vcl::PDFWriter::PageTransition::Regular; break;
2076 
2077                                         case presentation::FadeEffect_RANDOM :
2078                                         case presentation::FadeEffect_DISSOLVE :
2079                                         default: eType = vcl::PDFWriter::PageTransition::Dissolve; break;
2080                                     }
2081                                 }
2082                             }
2083 
2084                             if ( xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sEffect ) ||
2085                                 xPagePropSet->getPropertySetInfo( )->hasPropertyByName( sSpeed ) )
2086                             {
2087                                 pPDFExtOutDevData->SetPageTransition( eType, nTime );
2088                             }
2089                         }
2090                     }
2091                 }
2092 
2093                 Size        aPageSize( mpDoc->GetSdPage( 0, PageKind::Standard )->GetSize() );
2094                 Point aPoint( 0, 0 );
2095                 ::tools::Rectangle   aPageRect( aPoint, aPageSize );
2096 
2097                 // resolving links found in this page by the method ImpEditEngine::Paint
2098                 std::vector< vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = pPDFExtOutDevData->GetBookmarks();
2099                 for ( const auto& rBookmark : rBookmarks )
2100                 {
2101                     sal_Int32 nPage = ImplPDFGetBookmarkPage( rBookmark.aBookmark, *mpDoc );
2102                     if ( nPage != -1 )
2103                     {
2104                         if ( rBookmark.nLinkId != -1 )
2105                             pPDFExtOutDevData->SetLinkDest( rBookmark.nLinkId, pPDFExtOutDevData->CreateDest( aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle ) );
2106                         else
2107                             pPDFExtOutDevData->DescribeRegisteredDest( rBookmark.nDestId, aPageRect, nPage, vcl::PDFWriter::DestAreaType::FitRectangle );
2108                     }
2109                     else
2110                         pPDFExtOutDevData->SetLinkURL( rBookmark.nLinkId, rBookmark.aBookmark );
2111                 }
2112                 rBookmarks.clear();
2113                 //---> #i56629, #i40318
2114                 //get the page name, will be used as outline element in PDF bookmark pane
2115                 OUString aPageName = mpDoc->GetSdPage( static_cast<sal_uInt16>(nPageNumber) - 1 , PageKind::Standard )->GetName();
2116                 if( !aPageName.isEmpty() )
2117                 {
2118                     // Destination PageNum
2119                     const sal_Int32 nDestPageNum = CalcOutputPageNum(pPDFExtOutDevData, mpDoc, nPageNumber);
2120 
2121                     // insert the bookmark to this page into the NamedDestinations
2122                     if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
2123                         pPDFExtOutDevData->CreateNamedDest(aPageName, aPageRect, nDestPageNum);
2124 
2125                     // add the name to the outline, (almost) same code as in sc/source/ui/unoobj/docuno.cxx
2126                     // issue #i40318.
2127 
2128                     if( pPDFExtOutDevData->GetIsExportBookmarks() )
2129                     {
2130                         // Destination Export
2131                         const sal_Int32 nDestId =
2132                             pPDFExtOutDevData->CreateDest(aPageRect , nDestPageNum);
2133 
2134                         // Create a new outline item:
2135                         pPDFExtOutDevData->CreateOutlineItem( -1 , aPageName, nDestId );
2136                     }
2137                 }
2138                 //<--- #i56629, #i40318
2139             }
2140             catch (const uno::Exception&)
2141             {
2142             }
2143 
2144         }
2145     }
2146     else
2147     {
2148         uno::Reference< drawing::XShapes > xShapes;
2149         rSelection >>= xShapes;
2150 
2151         if( xShapes.is() && xShapes->getCount() )
2152         {
2153             SdrPageView* pPV = nullptr;
2154 
2155             ImplRenderPaintProc  aImplRenderPaintProc( mpDoc->GetLayerAdmin(),
2156                                 pOldSdView ? pOldSdView->GetSdrPageView() : nullptr, pPDFExtOutDevData );
2157 
2158             for( sal_uInt32 i = 0, nCount = xShapes->getCount(); i < nCount; i++ )
2159             {
2160                 uno::Reference< drawing::XShape > xShape;
2161                 xShapes->getByIndex( i ) >>= xShape;
2162 
2163                 if( xShape.is() )
2164                 {
2165                     SdrObject* pObj = SdrObject::getSdrObjectFromXShape( xShape );
2166                     if( pObj && pObj->getSdrPageFromSdrObject()
2167                         && aImplRenderPaintProc.IsVisible( pObj )
2168                             && aImplRenderPaintProc.IsPrintable( pObj ) )
2169                     {
2170                         if( !pPV )
2171                             pPV = aView.ShowSdrPage( pObj->getSdrPageFromSdrObject() );
2172 
2173                         if( pPV )
2174                             aView.MarkObj( pObj, pPV );
2175                     }
2176                 }
2177             }
2178             aView.DrawMarkedObj(*pOut);
2179         }
2180     }
2181 }
2182 
GetViewShell()2183 DrawViewShell* SdXImpressDocument::GetViewShell()
2184 {
2185     DrawViewShell* pViewSh = dynamic_cast<DrawViewShell*>(mpDocShell->GetViewShell());
2186     if (!pViewSh)
2187     {
2188         SAL_WARN("sd", "DrawViewShell not available!");
2189         return nullptr;
2190     }
2191     return pViewSh;
2192 }
2193 
paintTile(VirtualDevice & rDevice,int nOutputWidth,int nOutputHeight,int nTilePosX,int nTilePosY,::tools::Long nTileWidth,::tools::Long nTileHeight)2194 void SdXImpressDocument::paintTile( VirtualDevice& rDevice,
2195                             int nOutputWidth, int nOutputHeight,
2196                             int nTilePosX, int nTilePosY,
2197                             ::tools::Long nTileWidth, ::tools::Long nTileHeight )
2198 {
2199     DrawViewShell* pViewSh = GetViewShell();
2200     if (!pViewSh)
2201         return;
2202 
2203     // Scaling. Must convert from pixels to twips. We know
2204     // that VirtualDevices use a DPI of 96.
2205     // We specifically calculate these scales first as we're still
2206     // in TWIPs, and might as well minimize the number of conversions.
2207     const Fraction scale = conversionFract(o3tl::Length::px, o3tl::Length::twip);
2208     Fraction scaleX = Fraction(nOutputWidth, nTileWidth) * scale;
2209     Fraction scaleY = Fraction(nOutputHeight, nTileHeight) * scale;
2210 
2211     // svx seems to be the only component that works natively in
2212     // 100th mm rather than TWIP. It makes most sense just to
2213     // convert here and in getDocumentSize, and leave the tiled
2214     // rendering API working in TWIPs.
2215     ::tools::Long nTileWidthHMM = convertTwipToMm100( nTileWidth );
2216     ::tools::Long nTileHeightHMM = convertTwipToMm100( nTileHeight );
2217     int nTilePosXHMM = convertTwipToMm100( nTilePosX );
2218     int nTilePosYHMM = convertTwipToMm100( nTilePosY );
2219 
2220     MapMode aMapMode = rDevice.GetMapMode();
2221     aMapMode.SetMapUnit( MapUnit::Map100thMM );
2222     aMapMode.SetOrigin( Point( -nTilePosXHMM,
2223                                -nTilePosYHMM) );
2224     aMapMode.SetScaleX( scaleX );
2225     aMapMode.SetScaleY( scaleY );
2226 
2227     rDevice.SetMapMode( aMapMode );
2228 
2229     rDevice.SetOutputSizePixel( Size(nOutputWidth, nOutputHeight) );
2230 
2231     Point aPoint(nTilePosXHMM, nTilePosYHMM);
2232     Size aSize(nTileWidthHMM, nTileHeightHMM);
2233     ::tools::Rectangle aRect(aPoint, aSize);
2234 
2235     pViewSh->GetView()->CompleteRedraw(&rDevice, vcl::Region(aRect));
2236 
2237     LokChartHelper::PaintAllChartsOnTile(rDevice, nOutputWidth, nOutputHeight,
2238                                          nTilePosX, nTilePosY, nTileWidth, nTileHeight);
2239 }
2240 
selectPart(int nPart,int nSelect)2241 void SdXImpressDocument::selectPart(int nPart, int nSelect)
2242 {
2243     DrawViewShell* pViewSh = GetViewShell();
2244     if (!pViewSh)
2245         return;
2246 
2247     pViewSh->SelectPage(nPart, nSelect);
2248 }
2249 
moveSelectedParts(int nPosition,bool bDuplicate)2250 void SdXImpressDocument::moveSelectedParts(int nPosition, bool bDuplicate)
2251 {
2252     // Duplicating is currently unsupported.
2253     if (!bDuplicate)
2254         mpDoc->MovePages(nPosition);
2255 }
2256 
getPartInfo(int nPart)2257 OUString SdXImpressDocument::getPartInfo(int nPart)
2258 {
2259     DrawViewShell* pViewSh = GetViewShell();
2260     if (!pViewSh)
2261         return OUString();
2262 
2263     const bool bIsVisible = pViewSh->IsVisible(nPart);
2264     const bool bIsSelected = pViewSh->IsSelected(nPart);
2265     const sal_Int16 nMasterPageCount= pViewSh->GetDoc()->GetMasterSdPageCount(pViewSh->GetPageKind());
2266 
2267     OUString aPartInfo = "{ \"visible\": \"" +
2268         OUString::number(static_cast<unsigned int>(bIsVisible)) +
2269         "\", \"selected\": \"" +
2270         OUString::number(static_cast<unsigned int>(bIsSelected)) +
2271         "\", \"masterPageCount\": \"" +
2272         OUString::number(nMasterPageCount) +
2273         "\" }";
2274     return aPartInfo;
2275 }
2276 
setPart(int nPart,bool bAllowChangeFocus)2277 void SdXImpressDocument::setPart( int nPart, bool bAllowChangeFocus )
2278 {
2279     DrawViewShell* pViewSh = GetViewShell();
2280     if (!pViewSh)
2281         return;
2282 
2283     pViewSh->SwitchPage( nPart, bAllowChangeFocus );
2284 }
2285 
getParts()2286 int SdXImpressDocument::getParts()
2287 {
2288     // TODO: master pages?
2289     // Read: drviews1.cxx
2290     if (!mpDoc)
2291         return 0;
2292 
2293     return mpDoc->GetSdPageCount(PageKind::Standard);
2294 }
2295 
getPart()2296 int SdXImpressDocument::getPart()
2297 {
2298     DrawViewShell* pViewSh = GetViewShell();
2299     if (!pViewSh)
2300         return 0;
2301 
2302     return pViewSh->GetViewShellBase().getPart();
2303 }
2304 
getPartName(int nPart)2305 OUString SdXImpressDocument::getPartName( int nPart )
2306 {
2307     SdPage* pPage = mpDoc->GetSdPage( nPart, PageKind::Standard );
2308     if (!pPage)
2309     {
2310         SAL_WARN("sd", "DrawViewShell not available!");
2311         return OUString();
2312     }
2313 
2314     return pPage->GetName();
2315 }
2316 
getPartHash(int nPart)2317 OUString SdXImpressDocument::getPartHash( int nPart )
2318 {
2319     SdPage* pPage = mpDoc->GetSdPage( nPart, PageKind::Standard );
2320     if (!pPage)
2321     {
2322         SAL_WARN("sd", "DrawViewShell not available!");
2323         return OUString();
2324     }
2325 
2326     return OUString::number(pPage->GetHashCode());
2327 }
2328 
getDocWindow()2329 VclPtr<vcl::Window> SdXImpressDocument::getDocWindow()
2330 {
2331     SolarMutexGuard aGuard;
2332     DrawViewShell* pViewShell = GetViewShell();
2333     VclPtr<vcl::Window> pWindow;
2334     if (pViewShell)
2335         pWindow = pViewShell->GetActiveWindow();
2336 
2337     LokChartHelper aChartHelper(pViewShell->GetViewShell());
2338     VclPtr<vcl::Window> pChartWindow = aChartHelper.GetWindow();
2339     if (pChartWindow)
2340         pWindow = pChartWindow;
2341 
2342     return pWindow;
2343 }
2344 
setPartMode(int nPartMode)2345 void SdXImpressDocument::setPartMode( int nPartMode )
2346 {
2347     DrawViewShell* pViewSh = GetViewShell();
2348     if (!pViewSh)
2349         return;
2350 
2351     PageKind aPageKind( PageKind::Standard );
2352     switch ( nPartMode )
2353     {
2354     case LOK_PARTMODE_SLIDES:
2355         break;
2356     case LOK_PARTMODE_NOTES:
2357         aPageKind = PageKind::Notes;
2358         break;
2359     }
2360     pViewSh->SetPageKind( aPageKind );
2361 }
2362 
getDocumentSize()2363 Size SdXImpressDocument::getDocumentSize()
2364 {
2365     DrawViewShell* pViewSh = GetViewShell();
2366     if (!pViewSh)
2367         return Size();
2368 
2369     SdrView *pSdrView = pViewSh->GetView();
2370     if (!pSdrView)
2371         return Size();
2372 
2373     SdrPageView* pCurPageView = pSdrView->GetSdrPageView();
2374     if (!pCurPageView)
2375         return Size();
2376 
2377     Size aSize = pCurPageView->GetPageRect().GetSize();
2378     // Convert the size in 100th mm to TWIP
2379     // See paintTile above for further info.
2380     return Size(convertMm100ToTwip(aSize.getWidth()), convertMm100ToTwip(aSize.getHeight()));
2381 }
2382 
getPostIts(::tools::JsonWriter & rJsonWriter)2383 void SdXImpressDocument::getPostIts(::tools::JsonWriter& rJsonWriter)
2384 {
2385     auto commentsNode = rJsonWriter.startNode("comments");
2386     // Return annotations on master pages too ?
2387     const sal_uInt16 nMaxPages = mpDoc->GetPageCount();
2388     SdPage* pPage;
2389     for (sal_uInt16 nPage = 0; nPage < nMaxPages; ++nPage)
2390     {
2391         pPage = static_cast<SdPage*>(mpDoc->GetPage(nPage));
2392         const sd::AnnotationVector& aPageAnnotations = pPage->getAnnotations();
2393 
2394         for (const uno::Reference<office::XAnnotation>& xAnnotation : aPageAnnotations)
2395         {
2396             sal_uInt32 nID = sd::getAnnotationId(xAnnotation);
2397             OString nodeName = "comment" + OString::number(nID);
2398             auto commentNode = rJsonWriter.startNode(nodeName.getStr());
2399             rJsonWriter.put("id", nID);
2400             rJsonWriter.put("author", xAnnotation->getAuthor());
2401             rJsonWriter.put("dateTime", utl::toISO8601(xAnnotation->getDateTime()));
2402             uno::Reference<text::XText> xText(xAnnotation->getTextRange());
2403             rJsonWriter.put("text", xText->getString());
2404             rJsonWriter.put("parthash", pPage->GetHashCode());
2405             geometry::RealPoint2D const & rPoint = xAnnotation->getPosition();
2406             geometry::RealSize2D const & rSize = xAnnotation->getSize();
2407             ::tools::Rectangle aRectangle(Point(rPoint.X * 100.0, rPoint.Y * 100.0), Size(rSize.Width * 100.0, rSize.Height * 100.0));
2408             aRectangle = OutputDevice::LogicToLogic(aRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip));
2409             OString sRectangle = aRectangle.toString();
2410             rJsonWriter.put("rectangle", sRectangle.getStr());
2411         }
2412     }
2413 }
2414 
initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue> & rArguments)2415 void SdXImpressDocument::initializeForTiledRendering(const css::uno::Sequence<css::beans::PropertyValue>& rArguments)
2416 {
2417     SolarMutexGuard aGuard;
2418 
2419     if (DrawViewShell* pViewShell = GetViewShell())
2420     {
2421         DrawView* pDrawView = pViewShell->GetDrawView();
2422         for (const beans::PropertyValue& rValue : rArguments)
2423         {
2424             if (rValue.Name == ".uno:ShowBorderShadow" && rValue.Value.has<bool>())
2425                 pDrawView->SetPageShadowVisible(rValue.Value.get<bool>());
2426             else if (rValue.Name == ".uno:Author" && rValue.Value.has<OUString>())
2427                 pDrawView->SetAuthor(rValue.Value.get<OUString>());
2428             else if (rValue.Name == ".uno:SpellOnline" && rValue.Value.has<bool>())
2429                 mpDoc->SetOnlineSpell(rValue.Value.get<bool>());
2430         }
2431 
2432         // Disable comments if requested
2433         SdOptions* pOptions = SD_MOD()->GetSdOptions(mpDoc->GetDocumentType());
2434         pOptions->SetShowComments(comphelper::LibreOfficeKit::isTiledAnnotations());
2435 
2436         pViewShell->SetRuler(false);
2437         pViewShell->SetScrollBarsVisible(false);
2438 
2439         if (sd::Window* pWindow = pViewShell->GetActiveWindow())
2440         {
2441             // get the full page size in pixels
2442             pWindow->EnableMapMode();
2443             Size aSize(pWindow->LogicToPixel(pDrawView->GetSdrPageView()->GetPage()->GetSize()));
2444             // Disable map mode, so that it's possible to send mouse event
2445             // coordinates in logic units
2446             pWindow->EnableMapMode(false);
2447 
2448             // arrange UI elements again with new view size
2449             pViewShell->GetParentWindow()->SetSizePixel(aSize);
2450             pViewShell->Resize();
2451         }
2452 
2453         // Forces all images to be swapped in synchronously, this
2454         // ensures that images are available when paintTile is called
2455         // (whereas with async loading images start being loaded after
2456         //  we have painted the tile, resulting in an invalidate, followed
2457         //  by the tile being rerendered - which is wasteful and ugly).
2458         pDrawView->SetSwapAsynchron(false);
2459     }
2460 
2461     // when the "This document may contain formatting or content that cannot
2462     // be saved..." dialog appears, it is auto-cancelled with tiled rendering,
2463     // causing 'Save' being disabled; so let's always save to the original
2464     // format
2465     SvtSaveOptions().SetWarnAlienFormat(false);
2466 
2467     if (!getenv("LO_TESTNAME"))
2468         SvtSlideSorterBarOptions().SetVisibleImpressView(true);
2469 }
2470 
postKeyEvent(int nType,int nCharCode,int nKeyCode)2471 void SdXImpressDocument::postKeyEvent(int nType, int nCharCode, int nKeyCode)
2472 {
2473     SolarMutexGuard aGuard;
2474     SfxLokHelper::postKeyEventAsync(getDocWindow(), nType, nCharCode, nKeyCode);
2475 }
2476 
postMouseEvent(int nType,int nX,int nY,int nCount,int nButtons,int nModifier)2477 void SdXImpressDocument::postMouseEvent(int nType, int nX, int nY, int nCount, int nButtons, int nModifier)
2478 {
2479     SolarMutexGuard aGuard;
2480 
2481     DrawViewShell* pViewShell = GetViewShell();
2482     if (!pViewShell)
2483         return;
2484 
2485     double fScale = 1.0/TWIPS_PER_PIXEL;
2486 
2487     // check if user hit a chart which is being edited by him
2488     LokChartHelper aChartHelper(pViewShell->GetViewShell());
2489     if (aChartHelper.postMouseEvent(nType, nX, nY,
2490                                     nCount, nButtons, nModifier,
2491                                     fScale, fScale))
2492         return;
2493 
2494     // check if the user hit a chart which is being edited by someone else
2495     // and, if so, skip current mouse event
2496     if (nType != LOK_MOUSEEVENT_MOUSEMOVE)
2497     {
2498         if (LokChartHelper::HitAny(Point(nX, nY)))
2499             return;
2500     }
2501 
2502     const Point aPos(Point(convertTwipToMm100(nX), convertTwipToMm100(nY)));
2503     LokMouseEventData aMouseEventData(nType, aPos, nCount, MouseEventModifiers::SIMPLECLICK,
2504                                       nButtons, nModifier);
2505     SfxLokHelper::postMouseEventAsync(pViewShell->GetActiveWindow(), aMouseEventData);
2506 }
2507 
setTextSelection(int nType,int nX,int nY)2508 void SdXImpressDocument::setTextSelection(int nType, int nX, int nY)
2509 {
2510     SolarMutexGuard aGuard;
2511 
2512     DrawViewShell* pViewShell = GetViewShell();
2513     if (!pViewShell)
2514         return;
2515 
2516     LokChartHelper aChartHelper(pViewShell->GetViewShell());
2517     if (aChartHelper.setTextSelection(nType, nX, nY))
2518         return;
2519 
2520     Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
2521     switch (nType)
2522     {
2523     case LOK_SETTEXTSELECTION_START:
2524         pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/false, /*bClearMark=*/false);
2525         break;
2526     case LOK_SETTEXTSELECTION_END:
2527         pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/false);
2528         break;
2529     case LOK_SETTEXTSELECTION_RESET:
2530         pViewShell->SetCursorMm100Position(aPoint, /*bPoint=*/true, /*bClearMark=*/true);
2531         break;
2532     default:
2533         assert(false);
2534         break;
2535     }
2536 }
2537 
getSelection()2538 uno::Reference<datatransfer::XTransferable> SdXImpressDocument::getSelection()
2539 {
2540     SolarMutexGuard aGuard;
2541 
2542     DrawViewShell* pViewShell = GetViewShell();
2543     if (!pViewShell)
2544         return uno::Reference<datatransfer::XTransferable>();
2545 
2546     return pViewShell->GetSelectionTransferrable();
2547 }
2548 
setGraphicSelection(int nType,int nX,int nY)2549 void SdXImpressDocument::setGraphicSelection(int nType, int nX, int nY)
2550 {
2551     SolarMutexGuard aGuard;
2552 
2553     DrawViewShell* pViewShell = GetViewShell();
2554     if (!pViewShell)
2555         return;
2556 
2557     double fScale = 1.0/TWIPS_PER_PIXEL;
2558 
2559     LokChartHelper aChartHelper(pViewShell->GetViewShell());
2560     if (aChartHelper.setGraphicSelection(nType, nX, nY, fScale, fScale))
2561         return;
2562 
2563     Point aPoint(convertTwipToMm100(nX), convertTwipToMm100(nY));
2564     switch (nType)
2565     {
2566     case LOK_SETGRAPHICSELECTION_START:
2567         pViewShell->SetGraphicMm100Position(/*bStart=*/true, aPoint);
2568         break;
2569     case LOK_SETGRAPHICSELECTION_END:
2570         pViewShell->SetGraphicMm100Position(/*bStart=*/false, aPoint);
2571         break;
2572     default:
2573         assert(false);
2574         break;
2575     }
2576 }
2577 
resetSelection()2578 void SdXImpressDocument::resetSelection()
2579 {
2580     SolarMutexGuard aGuard;
2581 
2582     DrawViewShell* pViewShell = GetViewShell();
2583     if (!pViewShell)
2584         return;
2585 
2586     SdrView* pSdrView = pViewShell->GetView();
2587     if (!pSdrView)
2588         return;
2589 
2590     if (pSdrView->IsTextEdit())
2591     {
2592         // Reset the editeng selection.
2593         pSdrView->UnmarkAll();
2594         // Finish editing.
2595         pSdrView->SdrEndTextEdit();
2596     }
2597     // Reset graphic selection.
2598     pSdrView->UnmarkAll();
2599 }
2600 
setClientVisibleArea(const::tools::Rectangle & rRectangle)2601 void SdXImpressDocument::setClientVisibleArea(const ::tools::Rectangle& rRectangle)
2602 {
2603     SolarMutexGuard aGuard;
2604 
2605     DrawViewShell* pViewShell = GetViewShell();
2606     if (!pViewShell)
2607         return;
2608 
2609     pViewShell->GetViewShellBase().setLOKVisibleArea(rRectangle);
2610 }
2611 
setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard> & xClipboard)2612 void SdXImpressDocument::setClipboard(const uno::Reference<datatransfer::clipboard::XClipboard>& xClipboard)
2613 {
2614     SolarMutexGuard aGuard;
2615 
2616     DrawViewShell* pViewShell = GetViewShell();
2617     if (!pViewShell)
2618         return;
2619 
2620     pViewShell->GetActiveWindow()->SetClipboard(xClipboard);
2621 }
2622 
isMimeTypeSupported()2623 bool SdXImpressDocument::isMimeTypeSupported()
2624 {
2625     SolarMutexGuard aGuard;
2626     DrawViewShell* pViewShell = GetViewShell();
2627     if (!pViewShell)
2628         return false;
2629 
2630     TransferableDataHelper aDataHelper(TransferableDataHelper::CreateFromSystemClipboard(pViewShell->GetActiveWindow()));
2631     return EditEngine::HasValidData(aDataHelper.GetTransferable());
2632 }
2633 
getPointer()2634 PointerStyle SdXImpressDocument::getPointer()
2635 {
2636     SolarMutexGuard aGuard;
2637     DrawViewShell* pViewShell = GetViewShell();
2638     if (!pViewShell)
2639         return PointerStyle::Arrow;
2640 
2641     Window* pWindow = pViewShell->GetActiveWindow();
2642     if (!pWindow)
2643         return PointerStyle::Arrow;
2644 
2645     return pWindow->GetPointer();
2646 }
2647 
getForbiddenCharsTable()2648 uno::Reference< i18n::XForbiddenCharacters > SdXImpressDocument::getForbiddenCharsTable()
2649 {
2650     uno::Reference< i18n::XForbiddenCharacters > xForb(mxForbiddenCharacters);
2651 
2652     if( !xForb.is() )
2653         mxForbiddenCharacters = xForb = new SdUnoForbiddenCharsTable( mpDoc );
2654 
2655     return xForb;
2656 }
2657 
initializeDocument()2658 void SdXImpressDocument::initializeDocument()
2659 {
2660     if( mbClipBoard )
2661         return;
2662 
2663     switch( mpDoc->GetPageCount() )
2664     {
2665     case 1:
2666     {
2667         // nasty hack to detect clipboard document
2668         mbClipBoard = true;
2669         break;
2670     }
2671     case 0:
2672     {
2673         mpDoc->CreateFirstPages();
2674         mpDoc->StopWorkStartupDelay();
2675         break;
2676     }
2677     }
2678 }
2679 
getSdrModelFromUnoModel() const2680 SdrModel& SdXImpressDocument::getSdrModelFromUnoModel() const
2681 {
2682     OSL_ENSURE(GetDoc(), "No SdrModel in draw/Impress, should not happen");
2683     return *GetDoc(); // TTTT should be reference
2684 }
2685 
dispose()2686 void SAL_CALL SdXImpressDocument::dispose()
2687 {
2688     if( mbDisposed )
2689         return;
2690 
2691     ::SolarMutexGuard aGuard;
2692 
2693     if( mpDoc )
2694     {
2695         EndListening( *mpDoc );
2696         mpDoc = nullptr;
2697     }
2698 
2699     // Call the base class dispose() before setting the mbDisposed flag
2700     // to true.  The reason for this is that if close() has not yet been
2701     // called this is done in SfxBaseModel::dispose().  At the end of
2702     // that dispose() is called again.  It is important to forward this
2703     // second dispose() to the base class, too.
2704     // As a consequence the following code has to be able to be run twice.
2705     SfxBaseModel::dispose();
2706     mbDisposed = true;
2707 
2708     uno::Reference< container::XNameAccess > xLinks( mxLinks );
2709     if( xLinks.is() )
2710     {
2711         uno::Reference< lang::XComponent > xComp( xLinks, uno::UNO_QUERY );
2712         if( xComp.is() )
2713             xComp->dispose();
2714 
2715         xLinks = nullptr;
2716     }
2717 
2718     uno::Reference< drawing::XDrawPages > xDrawPagesAccess( mxDrawPagesAccess );
2719     if( xDrawPagesAccess.is() )
2720     {
2721         uno::Reference< lang::XComponent > xComp( xDrawPagesAccess, uno::UNO_QUERY );
2722         if( xComp.is() )
2723             xComp->dispose();
2724 
2725         xDrawPagesAccess = nullptr;
2726     }
2727 
2728     uno::Reference< drawing::XDrawPages > xMasterPagesAccess( mxMasterPagesAccess );
2729     if( xDrawPagesAccess.is() )
2730     {
2731         uno::Reference< lang::XComponent > xComp( xMasterPagesAccess, uno::UNO_QUERY );
2732         if( xComp.is() )
2733             xComp->dispose();
2734 
2735         xDrawPagesAccess = nullptr;
2736     }
2737 
2738     uno::Reference< container::XNameAccess > xLayerManager( mxLayerManager );
2739     if( xLayerManager.is() )
2740     {
2741         uno::Reference< lang::XComponent > xComp( xLayerManager, uno::UNO_QUERY );
2742         if( xComp.is() )
2743             xComp->dispose();
2744 
2745         xLayerManager = nullptr;
2746     }
2747 
2748     uno::Reference< container::XNameContainer > xCustomPresentationAccess( mxCustomPresentationAccess );
2749     if( xCustomPresentationAccess.is() )
2750     {
2751         uno::Reference< lang::XComponent > xComp( xCustomPresentationAccess, uno::UNO_QUERY );
2752         if( xComp.is() )
2753             xComp->dispose();
2754 
2755         xCustomPresentationAccess = nullptr;
2756     }
2757 
2758     mxDashTable = nullptr;
2759     mxGradientTable = nullptr;
2760     mxHatchTable = nullptr;
2761     mxBitmapTable = nullptr;
2762     mxTransGradientTable = nullptr;
2763     mxMarkerTable = nullptr;
2764     mxDrawingPool = nullptr;
2765 }
2766 
2767 
SdDrawPagesAccess(SdXImpressDocument & rMyModel)2768 SdDrawPagesAccess::SdDrawPagesAccess( SdXImpressDocument& rMyModel )  noexcept
2769 :   mpModel( &rMyModel)
2770 {
2771 }
2772 
~SdDrawPagesAccess()2773 SdDrawPagesAccess::~SdDrawPagesAccess() noexcept
2774 {
2775 }
2776 
2777 // XIndexAccess
getCount()2778 sal_Int32 SAL_CALL SdDrawPagesAccess::getCount()
2779 {
2780     ::SolarMutexGuard aGuard;
2781 
2782     if( nullptr == mpModel )
2783         throw lang::DisposedException();
2784 
2785     return mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2786 }
2787 
getByIndex(sal_Int32 Index)2788 uno::Any SAL_CALL SdDrawPagesAccess::getByIndex( sal_Int32 Index )
2789 {
2790     ::SolarMutexGuard aGuard;
2791 
2792     if( nullptr == mpModel )
2793         throw lang::DisposedException();
2794 
2795     uno::Any aAny;
2796 
2797     if( (Index < 0) || (Index >= mpModel->mpDoc->GetSdPageCount( PageKind::Standard ) ) )
2798         throw lang::IndexOutOfBoundsException();
2799 
2800     SdPage* pPage = mpModel->mpDoc->GetSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
2801     if( pPage )
2802     {
2803         uno::Reference< drawing::XDrawPage >  xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2804         aAny <<= xDrawPage;
2805     }
2806 
2807     return aAny;
2808 }
2809 
2810 // XNameAccess
getByName(const OUString & aName)2811 uno::Any SAL_CALL SdDrawPagesAccess::getByName( const OUString& aName )
2812 {
2813     ::SolarMutexGuard aGuard;
2814 
2815     if( nullptr == mpModel )
2816         throw lang::DisposedException();
2817 
2818     if( !aName.isEmpty() )
2819     {
2820         const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2821         sal_uInt16 nPage;
2822         for( nPage = 0; nPage < nCount; nPage++ )
2823         {
2824             SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2825             if(nullptr == pPage)
2826                 continue;
2827 
2828             if( aName == SdDrawPage::getPageApiName( pPage ) )
2829             {
2830                 uno::Any aAny;
2831                 uno::Reference< drawing::XDrawPage >  xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2832                 aAny <<= xDrawPage;
2833                 return aAny;
2834             }
2835         }
2836     }
2837 
2838     throw container::NoSuchElementException();
2839 }
2840 
getElementNames()2841 uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getElementNames()
2842 {
2843     ::SolarMutexGuard aGuard;
2844 
2845     if( nullptr == mpModel )
2846         throw lang::DisposedException();
2847 
2848     const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2849     uno::Sequence< OUString > aNames( nCount );
2850     OUString* pNames = aNames.getArray();
2851 
2852     sal_uInt16 nPage;
2853     for( nPage = 0; nPage < nCount; nPage++ )
2854     {
2855         SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2856         *pNames++ = SdDrawPage::getPageApiName( pPage );
2857     }
2858 
2859     return aNames;
2860 }
2861 
hasByName(const OUString & aName)2862 sal_Bool SAL_CALL SdDrawPagesAccess::hasByName( const OUString& aName )
2863 {
2864     ::SolarMutexGuard aGuard;
2865 
2866     if( nullptr == mpModel )
2867         throw lang::DisposedException();
2868 
2869     const sal_uInt16 nCount = mpModel->mpDoc->GetSdPageCount( PageKind::Standard );
2870     sal_uInt16 nPage;
2871     for( nPage = 0; nPage < nCount; nPage++ )
2872     {
2873         SdPage* pPage = mpModel->mpDoc->GetSdPage( nPage, PageKind::Standard );
2874         if(nullptr == pPage)
2875             continue;
2876 
2877         if( aName == SdDrawPage::getPageApiName( pPage ) )
2878             return true;
2879     }
2880 
2881     return false;
2882 }
2883 
2884 // XElementAccess
getElementType()2885 uno::Type SAL_CALL SdDrawPagesAccess::getElementType()
2886 {
2887     return cppu::UnoType<drawing::XDrawPage>::get();
2888 }
2889 
hasElements()2890 sal_Bool SAL_CALL SdDrawPagesAccess::hasElements()
2891 {
2892     return getCount() > 0;
2893 }
2894 
2895 // XDrawPages
2896 
2897 /**
2898  * Creates a new page with model at the specified position.
2899  * @returns corresponding SdDrawPage
2900  */
insertNewByIndex(sal_Int32 nIndex)2901 uno::Reference< drawing::XDrawPage > SAL_CALL SdDrawPagesAccess::insertNewByIndex( sal_Int32 nIndex )
2902 {
2903     ::SolarMutexGuard aGuard;
2904     comphelper::ProfileZone aZone("insertNewByIndex");
2905 
2906     if( nullptr == mpModel )
2907         throw lang::DisposedException();
2908 
2909     if( mpModel->mpDoc )
2910     {
2911         SdPage* pPage = mpModel->InsertSdPage( static_cast<sal_uInt16>(nIndex), false );
2912         if( pPage )
2913         {
2914             uno::Reference< drawing::XDrawPage > xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
2915             return xDrawPage;
2916         }
2917     }
2918     uno::Reference< drawing::XDrawPage > xDrawPage;
2919     return xDrawPage;
2920 }
2921 
2922 /**
2923  * Removes the specified SdDrawPage from the model and the internal list. It
2924  * only works, if there is at least one *normal* page in the model after
2925  * removing this page.
2926  */
remove(const uno::Reference<drawing::XDrawPage> & xPage)2927 void SAL_CALL SdDrawPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
2928 {
2929     ::SolarMutexGuard aGuard;
2930 
2931     if( nullptr == mpModel || mpModel->mpDoc == nullptr )
2932         throw lang::DisposedException();
2933 
2934     SdDrawDocument& rDoc = *mpModel->mpDoc;
2935 
2936     sal_uInt16 nPageCount = rDoc.GetSdPageCount( PageKind::Standard );
2937     if( nPageCount > 1 )
2938     {
2939         // get pPage from xPage and determine the Id (nPos ) afterwards
2940         SdDrawPage* pSvxPage = comphelper::getUnoTunnelImplementation<SdDrawPage>( xPage );
2941         if( pSvxPage )
2942         {
2943             SdPage* pPage = static_cast<SdPage*>(pSvxPage->GetSdrPage());
2944             if(pPage && ( pPage->GetPageKind() == PageKind::Standard ) )
2945             {
2946                 sal_uInt16 nPage = pPage->GetPageNum();
2947 
2948                 SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetPage( nPage+1 ) );
2949 
2950                 bool bUndo = rDoc.IsUndoEnabled();
2951                 if( bUndo )
2952                 {
2953                     // Add undo actions and delete the pages.  The order of adding
2954                     // the undo actions is important.
2955                     rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
2956                     rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
2957                     rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
2958                 }
2959 
2960                 rDoc.RemovePage( nPage ); // the page
2961                 rDoc.RemovePage( nPage ); // the notes page
2962 
2963                 if( bUndo )
2964                 {
2965                     rDoc.EndUndo();
2966                 }
2967             }
2968         }
2969     }
2970 
2971     mpModel->SetModified();
2972 }
2973 
2974 // XServiceInfo
2975 
getImplementationName()2976 OUString SAL_CALL SdDrawPagesAccess::getImplementationName(  )
2977 {
2978     return "SdDrawPagesAccess";
2979 }
2980 
supportsService(const OUString & ServiceName)2981 sal_Bool SAL_CALL SdDrawPagesAccess::supportsService( const OUString& ServiceName )
2982 {
2983     return cppu::supportsService(this, ServiceName);
2984 }
2985 
getSupportedServiceNames()2986 uno::Sequence< OUString > SAL_CALL SdDrawPagesAccess::getSupportedServiceNames(  )
2987 {
2988     return { "com.sun.star.drawing.DrawPages" };
2989 }
2990 
2991 // XComponent
dispose()2992 void SAL_CALL SdDrawPagesAccess::dispose(  )
2993 {
2994     mpModel = nullptr;
2995 }
2996 
addEventListener(const uno::Reference<lang::XEventListener> &)2997 void SAL_CALL SdDrawPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >&  )
2998 {
2999     OSL_FAIL( "not implemented!" );
3000 }
3001 
removeEventListener(const uno::Reference<lang::XEventListener> &)3002 void SAL_CALL SdDrawPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >&  )
3003 {
3004     OSL_FAIL( "not implemented!" );
3005 }
3006 
3007 
SdMasterPagesAccess(SdXImpressDocument & rMyModel)3008 SdMasterPagesAccess::SdMasterPagesAccess( SdXImpressDocument& rMyModel ) noexcept
3009 :   mpModel(&rMyModel)
3010 {
3011 }
3012 
~SdMasterPagesAccess()3013 SdMasterPagesAccess::~SdMasterPagesAccess() noexcept
3014 {
3015 }
3016 
3017 // XComponent
dispose()3018 void SAL_CALL SdMasterPagesAccess::dispose(  )
3019 {
3020     mpModel = nullptr;
3021 }
3022 
addEventListener(const uno::Reference<lang::XEventListener> &)3023 void SAL_CALL SdMasterPagesAccess::addEventListener( const uno::Reference< lang::XEventListener >&  )
3024 {
3025     OSL_FAIL( "not implemented!" );
3026 }
3027 
removeEventListener(const uno::Reference<lang::XEventListener> &)3028 void SAL_CALL SdMasterPagesAccess::removeEventListener( const uno::Reference< lang::XEventListener >&  )
3029 {
3030     OSL_FAIL( "not implemented!" );
3031 }
3032 
3033 // XIndexAccess
getCount()3034 sal_Int32 SAL_CALL SdMasterPagesAccess::getCount()
3035 {
3036     ::SolarMutexGuard aGuard;
3037 
3038     if( nullptr == mpModel->mpDoc )
3039         throw lang::DisposedException();
3040 
3041     return mpModel->mpDoc->GetMasterSdPageCount(PageKind::Standard);
3042 }
3043 
3044 /**
3045  * Provides a drawing::XDrawPage interface for accessing the Masterpage at the
3046  * specified position in the model.
3047  */
getByIndex(sal_Int32 Index)3048 uno::Any SAL_CALL SdMasterPagesAccess::getByIndex( sal_Int32 Index )
3049 {
3050     ::SolarMutexGuard aGuard;
3051     comphelper::ProfileZone aZone("SdMasterPagesAccess::getByIndex");
3052 
3053     if( nullptr == mpModel )
3054         throw lang::DisposedException();
3055 
3056     uno::Any aAny;
3057 
3058     if( (Index < 0) || (Index >= mpModel->mpDoc->GetMasterSdPageCount( PageKind::Standard ) ) )
3059         throw lang::IndexOutOfBoundsException();
3060 
3061     SdPage* pPage = mpModel->mpDoc->GetMasterSdPage( static_cast<sal_uInt16>(Index), PageKind::Standard );
3062     if( pPage )
3063     {
3064         uno::Reference< drawing::XDrawPage >  xDrawPage( pPage->getUnoPage(), uno::UNO_QUERY );
3065         aAny <<= xDrawPage;
3066     }
3067 
3068     return aAny;
3069 }
3070 
3071 // XElementAccess
getElementType()3072 uno::Type SAL_CALL SdMasterPagesAccess::getElementType()
3073 {
3074     return cppu::UnoType<drawing::XDrawPage>::get();
3075 }
3076 
hasElements()3077 sal_Bool SAL_CALL SdMasterPagesAccess::hasElements()
3078 {
3079     return getCount() > 0;
3080 }
3081 
3082 // XDrawPages
insertNewByIndex(sal_Int32 nInsertPos)3083 uno::Reference< drawing::XDrawPage > SAL_CALL SdMasterPagesAccess::insertNewByIndex( sal_Int32 nInsertPos )
3084 {
3085     ::SolarMutexGuard aGuard;
3086 
3087     if( nullptr == mpModel )
3088         throw lang::DisposedException();
3089 
3090     uno::Reference< drawing::XDrawPage > xDrawPage;
3091 
3092     SdDrawDocument* pDoc = mpModel->mpDoc;
3093     if( pDoc )
3094     {
3095         // calculate internal index and check for range errors
3096         const sal_Int32 nMPageCount = pDoc->GetMasterPageCount();
3097         nInsertPos = nInsertPos * 2 + 1;
3098         if( nInsertPos < 0 || nInsertPos > nMPageCount )
3099             nInsertPos = nMPageCount;
3100 
3101         // now generate a unique name for the new masterpage
3102         const OUString aStdPrefix( SdResId(STR_LAYOUT_DEFAULT_NAME) );
3103         OUString aPrefix( aStdPrefix );
3104 
3105         bool bUnique = true;
3106 
3107         std::vector<OUString> aPageNames;
3108         for (sal_Int32 nMaster = 1; nMaster < nMPageCount; ++nMaster)
3109         {
3110             const SdPage* pPage = static_cast<const SdPage*>(pDoc->GetMasterPage(static_cast<sal_uInt16>(nMaster)));
3111             if (!pPage)
3112                 continue;
3113             aPageNames.push_back(pPage->GetName());
3114             if (aPageNames.back() == aPrefix)
3115                 bUnique = false;
3116         }
3117 
3118         sal_Int32 i = 0;
3119         while (!bUnique)
3120         {
3121             aPrefix = aStdPrefix + " " + OUString::number(++i);
3122             bUnique = std::find(aPageNames.begin(), aPageNames.end(), aPrefix) == aPageNames.end();
3123         }
3124 
3125         OUString aLayoutName = aPrefix + SD_LT_SEPARATOR STR_LAYOUT_OUTLINE;
3126 
3127         // create styles
3128         static_cast<SdStyleSheetPool*>(pDoc->GetStyleSheetPool())->CreateLayoutStyleSheets( aPrefix );
3129 
3130         // get the first page for initial size and border settings
3131         SdPage* pPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Standard );
3132         SdPage* pRefNotesPage = mpModel->mpDoc->GetSdPage( sal_uInt16(0), PageKind::Notes);
3133 
3134         // create and insert new draw masterpage
3135         rtl::Reference<SdPage> pMPage = mpModel->mpDoc->AllocSdPage(true);
3136         pMPage->SetSize( pPage->GetSize() );
3137         pMPage->SetBorder( pPage->GetLeftBorder(),
3138                            pPage->GetUpperBorder(),
3139                            pPage->GetRightBorder(),
3140                            pPage->GetLowerBorder() );
3141         pMPage->SetLayoutName( aLayoutName );
3142         pDoc->InsertMasterPage(pMPage.get(),  static_cast<sal_uInt16>(nInsertPos));
3143 
3144         {
3145             // ensure default MasterPage fill
3146             pMPage->EnsureMasterPageDefaultBackground();
3147         }
3148 
3149         xDrawPage.set( pMPage->getUnoPage(), uno::UNO_QUERY );
3150 
3151         // create and insert new notes masterpage
3152         rtl::Reference<SdPage> pMNotesPage = mpModel->mpDoc->AllocSdPage(true);
3153         pMNotesPage->SetSize( pRefNotesPage->GetSize() );
3154         pMNotesPage->SetPageKind(PageKind::Notes);
3155         pMNotesPage->SetBorder( pRefNotesPage->GetLeftBorder(),
3156                                 pRefNotesPage->GetUpperBorder(),
3157                                 pRefNotesPage->GetRightBorder(),
3158                                 pRefNotesPage->GetLowerBorder() );
3159         pMNotesPage->SetLayoutName( aLayoutName );
3160         pDoc->InsertMasterPage(pMNotesPage.get(),  static_cast<sal_uInt16>(nInsertPos) + 1);
3161         pMNotesPage->SetAutoLayout(AUTOLAYOUT_NOTES, true, true);
3162         mpModel->SetModified();
3163     }
3164 
3165     return xDrawPage;
3166 }
3167 
3168 /**
3169  * Removes the specified SdMasterPage from the model and the internal list. It
3170  * only works, if there is no *normal* page using this page as MasterPage in
3171  * the model.
3172  */
remove(const uno::Reference<drawing::XDrawPage> & xPage)3173 void SAL_CALL SdMasterPagesAccess::remove( const uno::Reference< drawing::XDrawPage >& xPage )
3174 {
3175     ::SolarMutexGuard aGuard;
3176 
3177     if( nullptr == mpModel || mpModel->mpDoc == nullptr )
3178         throw lang::DisposedException();
3179 
3180     SdMasterPage* pSdPage = comphelper::getUnoTunnelImplementation<SdMasterPage>( xPage );
3181     if(pSdPage == nullptr)
3182         return;
3183 
3184     SdPage* pPage = dynamic_cast< SdPage* > (pSdPage->GetSdrPage());
3185 
3186     DBG_ASSERT( pPage && pPage->IsMasterPage(), "SdMasterPage is not masterpage?");
3187 
3188     if( !pPage || !pPage->IsMasterPage() || (mpModel->mpDoc->GetMasterPageUserCount(pPage) > 0))
3189         return; //Todo: this should be excepted
3190 
3191     // only standard pages can be removed directly
3192     if( pPage->GetPageKind() != PageKind::Standard )
3193         return;
3194 
3195     sal_uInt16 nPage = pPage->GetPageNum();
3196 
3197     SdDrawDocument& rDoc = *mpModel->mpDoc;
3198 
3199     SdPage* pNotesPage = static_cast< SdPage* >( rDoc.GetMasterPage( nPage+1 ) );
3200 
3201     bool bUndo = rDoc.IsUndoEnabled();
3202     if( bUndo )
3203     {
3204         // Add undo actions and delete the pages.  The order of adding
3205         // the undo actions is important.
3206         rDoc.BegUndo( SdResId( STR_UNDO_DELETEPAGES ) );
3207         rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pNotesPage));
3208         rDoc.AddUndo(rDoc.GetSdrUndoFactory().CreateUndoDeletePage(*pPage));
3209     }
3210 
3211     // remove both pages
3212     rDoc.RemoveMasterPage( nPage );
3213     rDoc.RemoveMasterPage( nPage );
3214 
3215     if( bUndo )
3216     {
3217         rDoc.EndUndo();
3218     }
3219 }
3220 
3221 // XServiceInfo
3222 
getImplementationName()3223 OUString SAL_CALL SdMasterPagesAccess::getImplementationName(  )
3224 {
3225     return "SdMasterPagesAccess";
3226 }
3227 
supportsService(const OUString & ServiceName)3228 sal_Bool SAL_CALL SdMasterPagesAccess::supportsService( const OUString& ServiceName )
3229 {
3230     return cppu::supportsService(this, ServiceName);
3231 }
3232 
getSupportedServiceNames()3233 uno::Sequence< OUString > SAL_CALL SdMasterPagesAccess::getSupportedServiceNames(  )
3234 {
3235     return { "com.sun.star.drawing.MasterPages" };
3236 }
3237 
3238 
SdDocLinkTargets(SdXImpressDocument & rMyModel)3239 SdDocLinkTargets::SdDocLinkTargets( SdXImpressDocument& rMyModel ) noexcept
3240 : mpModel( &rMyModel )
3241 {
3242 }
3243 
~SdDocLinkTargets()3244 SdDocLinkTargets::~SdDocLinkTargets() noexcept
3245 {
3246 }
3247 
3248 // XComponent
dispose()3249 void SAL_CALL SdDocLinkTargets::dispose(  )
3250 {
3251     mpModel = nullptr;
3252 }
3253 
addEventListener(const uno::Reference<lang::XEventListener> &)3254 void SAL_CALL SdDocLinkTargets::addEventListener( const uno::Reference< lang::XEventListener >&  )
3255 {
3256     OSL_FAIL( "not implemented!" );
3257 }
3258 
removeEventListener(const uno::Reference<lang::XEventListener> &)3259 void SAL_CALL SdDocLinkTargets::removeEventListener( const uno::Reference< lang::XEventListener >&  )
3260 {
3261     OSL_FAIL( "not implemented!" );
3262 }
3263 
3264 // XNameAccess
getByName(const OUString & aName)3265 uno::Any SAL_CALL SdDocLinkTargets::getByName( const OUString& aName )
3266 {
3267     ::SolarMutexGuard aGuard;
3268 
3269     if( nullptr == mpModel )
3270         throw lang::DisposedException();
3271 
3272     SdPage* pPage = FindPage( aName );
3273 
3274     if( pPage == nullptr )
3275         throw container::NoSuchElementException();
3276 
3277     uno::Any aAny;
3278 
3279     uno::Reference< beans::XPropertySet > xProps( pPage->getUnoPage(), uno::UNO_QUERY );
3280     if( xProps.is() )
3281         aAny <<= xProps;
3282 
3283     return aAny;
3284 }
3285 
getElementNames()3286 uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getElementNames()
3287 {
3288     ::SolarMutexGuard aGuard;
3289 
3290     if( nullptr == mpModel )
3291         throw lang::DisposedException();
3292 
3293     SdDrawDocument* pDoc = mpModel->GetDoc();
3294     if( pDoc == nullptr )
3295     {
3296         return { };
3297     }
3298 
3299     if( pDoc->GetDocumentType() == DocumentType::Draw )
3300     {
3301         const sal_uInt16 nMaxPages = pDoc->GetSdPageCount( PageKind::Standard );
3302         const sal_uInt16 nMaxMasterPages = pDoc->GetMasterSdPageCount( PageKind::Standard );
3303 
3304         uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages );
3305         OUString* pStr = aSeq.getArray();
3306 
3307         sal_uInt16 nPage;
3308         // standard pages
3309         for( nPage = 0; nPage < nMaxPages; nPage++ )
3310             *pStr++ = pDoc->GetSdPage( nPage, PageKind::Standard )->GetName();
3311 
3312         // master pages
3313         for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3314             *pStr++ = pDoc->GetMasterSdPage( nPage, PageKind::Standard )->GetName();
3315         return aSeq;
3316     }
3317     else
3318     {
3319         const sal_uInt16 nMaxPages = pDoc->GetPageCount();
3320         const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
3321 
3322         uno::Sequence< OUString > aSeq( nMaxPages + nMaxMasterPages );
3323         OUString* pStr = aSeq.getArray();
3324 
3325         sal_uInt16 nPage;
3326         // standard pages
3327         for( nPage = 0; nPage < nMaxPages; nPage++ )
3328             *pStr++ = static_cast<SdPage*>(pDoc->GetPage( nPage ))->GetName();
3329 
3330         // master pages
3331         for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3332             *pStr++ = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ))->GetName();
3333         return aSeq;
3334     }
3335 }
3336 
hasByName(const OUString & aName)3337 sal_Bool SAL_CALL SdDocLinkTargets::hasByName( const OUString& aName )
3338 {
3339     ::SolarMutexGuard aGuard;
3340 
3341     if( nullptr == mpModel )
3342         throw lang::DisposedException();
3343 
3344     return FindPage( aName ) != nullptr;
3345 }
3346 
3347 // container::XElementAccess
getElementType()3348 uno::Type SAL_CALL SdDocLinkTargets::getElementType()
3349 {
3350     return cppu::UnoType<beans::XPropertySet>::get();
3351 }
3352 
hasElements()3353 sal_Bool SAL_CALL SdDocLinkTargets::hasElements()
3354 {
3355     ::SolarMutexGuard aGuard;
3356 
3357     if( nullptr == mpModel )
3358         throw lang::DisposedException();
3359 
3360     return mpModel->GetDoc() != nullptr;
3361 }
3362 
FindPage(std::u16string_view rName) const3363 SdPage* SdDocLinkTargets::FindPage( std::u16string_view rName ) const
3364 {
3365     SdDrawDocument* pDoc = mpModel->GetDoc();
3366     if( pDoc == nullptr )
3367         return nullptr;
3368 
3369     const sal_uInt16 nMaxPages = pDoc->GetPageCount();
3370     const sal_uInt16 nMaxMasterPages = pDoc->GetMasterPageCount();
3371 
3372     sal_uInt16 nPage;
3373     SdPage* pPage;
3374 
3375     const bool bDraw = pDoc->GetDocumentType() == DocumentType::Draw;
3376 
3377     // standard pages
3378     for( nPage = 0; nPage < nMaxPages; nPage++ )
3379     {
3380         pPage = static_cast<SdPage*>(pDoc->GetPage( nPage ));
3381         if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
3382             return pPage;
3383     }
3384 
3385     // master pages
3386     for( nPage = 0; nPage < nMaxMasterPages; nPage++ )
3387     {
3388         pPage = static_cast<SdPage*>(pDoc->GetMasterPage( nPage ));
3389         if( (pPage->GetName() == rName) && (!bDraw || (pPage->GetPageKind() == PageKind::Standard)) )
3390             return pPage;
3391     }
3392 
3393     return nullptr;
3394 }
3395 
3396 // XServiceInfo
getImplementationName()3397 OUString SAL_CALL SdDocLinkTargets::getImplementationName()
3398 {
3399     return "SdDocLinkTargets";
3400 }
3401 
supportsService(const OUString & ServiceName)3402 sal_Bool SAL_CALL SdDocLinkTargets::supportsService( const OUString& ServiceName )
3403 {
3404     return cppu::supportsService( this, ServiceName );
3405 }
3406 
getSupportedServiceNames()3407 uno::Sequence< OUString > SAL_CALL SdDocLinkTargets::getSupportedServiceNames()
3408 {
3409     return { "com.sun.star.document.LinkTargets" };
3410 }
3411 
GetModel(SdDrawDocument const & rDocument)3412 rtl::Reference< SdXImpressDocument > SdXImpressDocument::GetModel( SdDrawDocument const & rDocument )
3413 {
3414     rtl::Reference< SdXImpressDocument > xRet;
3415     ::sd::DrawDocShell* pDocShell(rDocument.GetDocSh());
3416     if( pDocShell )
3417     {
3418         uno::Reference<frame::XModel> xModel(pDocShell->GetModel());
3419 
3420         xRet.set( dynamic_cast< SdXImpressDocument* >( xModel.get() ) );
3421     }
3422 
3423     return xRet;
3424 }
3425 
NotifyDocumentEvent(SdDrawDocument const & rDocument,const OUString & rEventName)3426 void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName )
3427 {
3428     rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) );
3429 
3430     if( xModel.is() )
3431     {
3432         uno::Reference< uno::XInterface > xSource( static_cast<uno::XWeak*>( xModel.get() ) );
3433         css::document::EventObject aEvent( xSource, rEventName );
3434         xModel->notifyEvent(aEvent );
3435     }
3436 }
3437 
NotifyDocumentEvent(SdDrawDocument const & rDocument,const OUString & rEventName,const uno::Reference<uno::XInterface> & xSource)3438 void NotifyDocumentEvent( SdDrawDocument const & rDocument, const OUString& rEventName, const uno::Reference< uno::XInterface >& xSource )
3439 {
3440     rtl::Reference< SdXImpressDocument > xModel( SdXImpressDocument::GetModel( rDocument ) );
3441 
3442     if( xModel.is() )
3443     {
3444         css::document::EventObject aEvent( xSource, rEventName );
3445         xModel->notifyEvent(aEvent );
3446     }
3447 }
3448 
3449 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3450