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