1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <oox/drawingml/clrscheme.hxx>
22 #include <oox/token/namespaces.hxx>
23 #include <oox/token/tokens.hxx>
24 #include <oox/token/relationship.hxx>
25 #include <oox/ole/vbaproject.hxx>
26 #include "epptooxml.hxx"
27 #include <oox/export/shapes.hxx>
29 #include <comphelper/sequenceashashmap.hxx>
30 #include <comphelper/storagehelper.hxx>
31 #include <comphelper/xmltools.hxx>
32 #include <sax/fshelper.hxx>
33 #include <rtl/ustrbuf.hxx>
34 #include <sal/log.hxx>
35 #include <tools/UnitConversion.hxx>
36 #include <tools/datetime.hxx>
37 #include <unotools/securityoptions.hxx>
38 #include <com/sun/star/animations/TransitionType.hpp>
39 #include <com/sun/star/animations/TransitionSubType.hpp>
40 #include <com/sun/star/beans/XPropertySetInfo.hpp>
41 #include <com/sun/star/drawing/FillStyle.hpp>
42 #include <com/sun/star/drawing/XDrawPages.hpp>
43 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
44 #include <com/sun/star/embed/ElementModes.hpp>
45 #include <com/sun/star/geometry/RealPoint2D.hpp>
46 #include <com/sun/star/office/XAnnotationEnumeration.hpp>
47 #include <com/sun/star/office/XAnnotationAccess.hpp>
48 #include <com/sun/star/presentation/AnimationSpeed.hpp>
49 #include <com/sun/star/util/DateTime.hpp>
50 #include <com/sun/star/task/XStatusIndicator.hpp>
51 #include <com/sun/star/frame/XModel.hpp>
52 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 #include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
54 #include <com/sun/star/container/XIndexContainer.hpp>
55 #include <com/sun/star/container/XNamed.hpp>
56 #include <com/sun/star/presentation/XPresentationSupplier.hpp>
57 #include <comphelper/diagnose_ex.hxx>
59 #include <oox/export/utils.hxx>
60 #include <oox/export/ThemeExport.hxx>
61 #include <docmodel/theme/Theme.hxx>
63 #include "pptx-animations.hxx"
64 #include "../ppt/pptanimations.hxx"
66 #include <i18nlangtag/languagetag.hxx>
67 #include <svx/sdrmasterpagedescriptor.hxx>
68 #include <svx/svdpage.hxx>
69 #include <svx/unoapi.hxx>
70 #include <svx/svdogrp.hxx>
71 #include <svx/ColorSets.hxx>
75 #include <vcl/svapp.hxx>
76 #include <vcl/settings.hxx>
78 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
79 #include <com/sun/star/document/XStorageBasedDocument.hpp>
81 #if OSL_DEBUG_LEVEL > 1
82 #include <com/sun/star/drawing/RectanglePoint.hpp>
85 // presentation namespaces
86 #define PNMSS FSNS(XML_xmlns, XML_a), this->getNamespaceURL(OOX_NS(dml)), \
87 FSNS(XML_xmlns, XML_p), this->getNamespaceURL(OOX_NS(ppt)), \
88 FSNS(XML_xmlns, XML_r), this->getNamespaceURL(OOX_NS(officeRel)), \
89 FSNS(XML_xmlns, XML_p14), this->getNamespaceURL(OOX_NS(p14)), \
90 FSNS(XML_xmlns, XML_p15), this->getNamespaceURL(OOX_NS(p15)), \
91 FSNS(XML_xmlns, XML_mc), this->getNamespaceURL(OOX_NS(mce))
93 // presentationPr namespace
94 #define PPRNMSS FSNS(XML_xmlns, XML_a), this->getNamespaceURL(OOX_NS(dml)), \
95 FSNS(XML_xmlns, XML_r), this->getNamespaceURL(OOX_NS(officeRel)), \
96 FSNS(XML_xmlns, XML_p), this->getNamespaceURL(OOX_NS(ppt))
98 using namespace ::com::sun::star
;
99 using namespace ::com::sun::star::animations
;
100 using namespace ::com::sun::star::beans
;
101 using namespace ::com::sun::star::container
;
102 using namespace ::com::sun::star::drawing
;
103 using namespace ::com::sun::star::geometry
;
104 using namespace ::com::sun::star::presentation
;
105 using namespace ::com::sun::star::office
;
106 using namespace ::com::sun::star::text
;
107 using namespace ::com::sun::star::uno
;
108 using namespace ::com::sun::star::util
;
109 using namespace ::ppt
;
110 using ::com::sun::star::beans::XPropertySet
;
111 using ::com::sun::star::beans::XPropertySetInfo
;
112 using ::sax_fastparser::FSHelperPtr
;
113 using namespace oox::drawingml
;
114 using namespace oox::core
;
116 #if OSL_DEBUG_LEVEL > 1
117 void dump_pset(Reference
< XPropertySet
> const& rXPropSet
);
123 class PowerPointShapeExport
: public ShapeExport
125 PowerPointExport
& mrExport
;
129 PowerPointShapeExport(FSHelperPtr pFS
, ShapeHashMap
* pShapeMap
, PowerPointExport
* pFB
);
130 void SetMaster(bool bMaster
);
131 void SetPageType(PageType ePageType
);
132 ShapeExport
& WriteNonVisualProperties(const Reference
< XShape
>& xShape
) override
;
133 ShapeExport
& WriteTextShape(const Reference
< XShape
>& xShape
) override
;
134 ShapeExport
& WriteUnknownShape(const Reference
< XShape
>& xShape
) override
;
135 ShapeExport
& WritePlaceholderShape(const Reference
< XShape
>& xShape
, PlaceholderType ePlaceholder
);
136 /** Writes a placeholder shape that references the placeholder on the master slide */
137 ShapeExport
& WritePlaceholderReferenceShape(PlaceholderType ePlaceholder
, sal_Int32 nReferencedPlaceholderIdx
, PageType ePageType
, const Reference
<XPropertySet
>& rXPagePropSet
);
138 ShapeExport
& WritePageShape(const Reference
< XShape
>& xShape
, PageType ePageType
, bool bPresObj
);
139 /** Writes textbody of a placeholder that references the placeholder on the master slide */
140 ShapeExport
& WritePlaceholderReferenceTextBody(PlaceholderType ePlaceholder
, PageType ePageType
, const Reference
<XPropertySet
>& xPagePropSet
);
143 bool WritePlaceholder(const Reference
< XShape
>& xShape
, PlaceholderType ePlaceholder
, bool bMaster
);
149 void WriteSndAc(const FSHelperPtr
& pFS
, const OUString
& sSoundRelId
, const OUString
& sSoundName
)
151 pFS
->startElementNS(XML_p
, XML_sndAc
);
152 pFS
->startElementNS(XML_p
, XML_stSnd
);
153 pFS
->singleElementNS(XML_p
, XML_snd
, FSNS(XML_r
, XML_embed
),
154 sax_fastparser::UseIf(sSoundRelId
, !sSoundRelId
.isEmpty()), XML_name
,
155 sax_fastparser::UseIf(sSoundName
, !sSoundName
.isEmpty()));
156 pFS
->endElement(FSNS(XML_p
, XML_stSnd
));
157 pFS
->endElement(FSNS(XML_p
, XML_sndAc
));
160 const char* getPlaceholderTypeName(PlaceholderType ePlaceholder
)
162 switch (ePlaceholder
)
183 SAL_INFO("sd.eppt", "warning: unhandled placeholder type: " << ePlaceholder
);
192 struct PPTXLayoutInfo
201 const PPTXLayoutInfo aLayoutInfo
[OOXML_LAYOUT_SIZE
] =
203 { 0, "Title Slide", "title" },
204 { 1, "Title and text", "tx" },
205 { 2, "Title and chart", "chart" },
206 { 3, "Title, text on left, text on right", "twoObj" },
207 { 4, "Title, text on left and chart on right", "txAndChart" },
208 { 6, "Title, text on left, clip art on right", "txAndClipArt" },
209 { 6, "Title, text on left, media on right", "txAndMedia" },
210 { 7, "Title, chart on left and text on right", "chartAndTx" },
211 { 8, "Title and table", "tbl" },
212 { 9, "Title, clipart on left, text on right", "clipArtAndTx" },
213 { 10, "Title, text on left, object on right", "txAndObj" },
214 { 1, "Title and object", "obj" },
215 { 12, "Title, text on left, two objects on right", "txAndTwoObj" },
216 { 13, "Title, object on left, text on right", "objAndTx" },
217 { 14, "Title, object on top, text on bottom", "objOverTx" },
218 { 15, "Title, two objects on left, text on right", "twoObjAndTx" },
219 { 16, "Title, two objects on top, text on bottom", "twoObjOverTx" },
220 { 17, "Title, text on top, object on bottom", "txOverObj" },
221 { 18, "Title and four objects", "fourObj" },
222 { 19, "Title Only", "titleOnly" },
223 { 20, "Blank Slide", "blank" },
224 { 21, "Vertical title on right, vertical text on top, chart on bottom", "vertTitleAndTxOverChart" },
225 { 22, "Vertical title on right, vertical text on left", "vertTitleAndTx" },
226 { 23, "Title and vertical text body", "vertTx" },
227 { 24, "Title, clip art on left, vertical text on right", "clipArtAndVertTx" },
228 { 20, "Title, two objects each with text", "twoTxTwoObj" },
229 { 15, "Title, two objects on left, one object on right", "twoObjAndObj" },
230 { 20, "Title, object and caption text", "objTx" },
231 { 20, "Title, picture, and caption text", "picTx" },
232 { 20, "Section header title and subtitle text", "secHead" },
233 { 32, "Object only", "objOnly" },
234 { 12, "Title, one object on left, two objects on right", "objAndTwoObj" },
235 { 20, "Title, media on left, text on right", "mediaAndTx" },
236 { 34, "Title, 6 Content", "blank" }, // not defined in OOXML => blank
237 { 2, "Title and diagram", "dgm" },
238 { 0, "Custom layout defined by user", "cust" },
241 PowerPointShapeExport::PowerPointShapeExport(FSHelperPtr pFS
, ShapeHashMap
* pShapeMap
,
242 PowerPointExport
* pFB
)
243 : ShapeExport(XML_p
, std::move(pFS
), pShapeMap
, pFB
)
245 , mePageType(UNDEFINED
)
250 void PowerPointShapeExport::SetMaster(bool bMaster
)
255 void PowerPointShapeExport::SetPageType(PageType ePageType
)
257 mePageType
= ePageType
;
260 ShapeExport
& PowerPointShapeExport::WriteNonVisualProperties(const Reference
< XShape
>&)
262 GetFS()->singleElementNS(XML_p
, XML_nvPr
);
267 ShapeExport
& PowerPointShapeExport::WriteTextShape(const Reference
< XShape
>& xShape
)
269 OUString sShapeType
= xShape
->getShapeType();
271 SAL_INFO("sd.eppt", "shape(text) : " << sShapeType
.toUtf8());
273 if (sShapeType
== "com.sun.star.drawing.TextShape" || sShapeType
== "com.sun.star.drawing.GraphicObjectShape")
275 ShapeExport::WriteTextShape(xShape
);
277 else if (sShapeType
== "com.sun.star.presentation.DateTimeShape")
279 if (!WritePlaceholder(xShape
, DateAndTime
, mbMaster
))
280 ShapeExport::WriteTextShape(xShape
);
282 else if (sShapeType
== "com.sun.star.presentation.FooterShape")
284 if (!WritePlaceholder(xShape
, Footer
, mbMaster
))
285 ShapeExport::WriteTextShape(xShape
);
287 else if (sShapeType
== "com.sun.star.presentation.HeaderShape")
289 if (!WritePlaceholder(xShape
, Header
, mbMaster
))
290 ShapeExport::WriteTextShape(xShape
);
292 else if (sShapeType
== "com.sun.star.presentation.NotesShape")
294 if (mePageType
== NOTICE
&& mrExport
.GetPresObj())
295 WritePlaceholderShape(xShape
, Notes
);
297 ShapeExport::WriteTextShape(xShape
);
299 else if (sShapeType
== "com.sun.star.presentation.OutlinerShape")
301 if (!WritePlaceholder(xShape
, Outliner
, mbMaster
))
302 ShapeExport::WriteTextShape(xShape
);
304 else if (sShapeType
== "com.sun.star.presentation.SlideNumberShape")
306 if (!WritePlaceholder(xShape
, SlideNumber
, mbMaster
))
307 ShapeExport::WriteTextShape(xShape
);
309 else if (sShapeType
== "com.sun.star.presentation.TitleTextShape")
311 if (!WritePlaceholder(xShape
, Title
, mbMaster
))
312 ShapeExport::WriteTextShape(xShape
);
315 SAL_WARN("sd.eppt", "PowerPointShapeExport::WriteTextShape: shape of type '" << sShapeType
<< "' is ignored");
320 ShapeExport
& PowerPointShapeExport::WriteUnknownShape(const Reference
< XShape
>& xShape
)
322 OUString sShapeType
= xShape
->getShapeType();
324 SAL_INFO("sd.eppt", "shape(unknown): " << sShapeType
.toUtf8());
326 if (sShapeType
== "com.sun.star.presentation.PageShape")
328 WritePageShape(xShape
, mePageType
, mrExport
.GetPresObj());
330 else if (sShapeType
== "com.sun.star.presentation.SubtitleShape")
332 if(mePageType
!= MASTER
)
334 if (!WritePlaceholder(xShape
, Subtitle
, mbMaster
))
335 ShapeExport::WriteTextShape(xShape
);
339 SAL_WARN("sd.eppt", "unknown shape not handled: " << sShapeType
.toUtf8());
344 PowerPointExport::PowerPointExport(const Reference
< XComponentContext
>& rContext
, const uno::Sequence
<uno::Any
>& rArguments
)
345 : XmlFilterBase(rContext
)
346 , mpAuthorIDs( new SvtSecurityMapPersonalInfo
)
347 , mnLayoutFileIdMax(1)
348 , mnSlideIdMax(1 << 8)
349 , mnSlideMasterIdMax(1U << 31)
350 , mnAnimationNodeIdMax(1)
352 , mbCreateNotes(false)
353 , mnPlaceholderIndexMax(1)
355 comphelper::SequenceAsHashMap
aArgumentsMap(rArguments
);
356 mbPptm
= aArgumentsMap
.getUnpackedValueOrDefault(u
"IsPPTM"_ustr
, false);
357 mbExportTemplate
= aArgumentsMap
.getUnpackedValueOrDefault(u
"IsTemplate"_ustr
, false);
360 PowerPointExport::~PowerPointExport()
364 void PowerPointExport::writeDocumentProperties()
366 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(mXModel
, uno::UNO_QUERY
);
367 uno::Reference
<document::XDocumentProperties
> xDocProps
= xDPS
->getDocumentProperties();
371 bool bSecurityOptOpenReadOnly
= false;
372 uno::Reference
< lang::XMultiServiceFactory
> xFactory(mXModel
, uno::UNO_QUERY
);
373 uno::Reference
< beans::XPropertySet
> xSettings(xFactory
->createInstance(u
"com.sun.star.document.Settings"_ustr
), uno::UNO_QUERY
);
376 xSettings
->getPropertyValue(u
"LoadReadonly"_ustr
) >>= bSecurityOptOpenReadOnly
;
381 exportDocumentProperties(xDocProps
, bSecurityOptOpenReadOnly
);
384 exportCustomFragments();
387 bool PowerPointExport::importDocument() noexcept
392 bool PowerPointExport::exportDocument()
394 drawingml::DrawingML::ResetMlCounters();
395 auto& rGraphicExportCache
= drawingml::GraphicExportCache::get();
397 rGraphicExportCache
.push();
401 mXModel
= getModel();
403 //write document properties
404 writeDocumentProperties();
406 addRelation(oox::getRelationship(Relationship::OFFICEDOCUMENT
), u
"ppt/presentation.xml");
411 if (mbExportTemplate
)
413 aMediaType
= "application/vnd.ms-powerpoint.template.macroEnabled.main+xml";
417 aMediaType
= "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml";
422 if (mbExportTemplate
)
424 aMediaType
= "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml";
428 aMediaType
= "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml";
432 mPresentationFS
= openFragmentStreamWithSerializer(u
"ppt/presentation.xml"_ustr
, aMediaType
);
434 addRelation(mPresentationFS
->getOutputStream(),
435 oox::getRelationship(Relationship::THEME
),
436 u
"theme/theme1.xml");
438 mPresentationFS
->startElementNS(XML_p
, XML_presentation
, PNMSS
);
440 mXStatusIndicator
= getStatusIndicator();
442 std::vector
< PropertyValue
> aProperties
;
443 PropertyValue aProperty
;
444 aProperty
.Name
= "BaseURI";
445 aProperty
.Value
<<= getFileUrl();
446 aProperties
.push_back(aProperty
);
448 exportPPT(aProperties
);
450 mPresentationFS
->singleElementNS(XML_p
, XML_sldSz
,
451 XML_cx
, OString::number(PPTtoEMU(maDestPageSize
.Width
)),
452 XML_cy
, OString::number(PPTtoEMU(maDestPageSize
.Height
)));
453 // for some reason if added before slides list it will not load the slides (alas with error reports) in mso
454 mPresentationFS
->singleElementNS(XML_p
, XML_notesSz
,
455 XML_cx
, OString::number(PPTtoEMU(maNotesPageSize
.Width
)),
456 XML_cy
, OString::number(PPTtoEMU(maNotesPageSize
.Height
)));
458 WriteCustomSlideShow();
460 WritePresentationProps();
466 WriteModifyVerifier();
468 mPresentationFS
->endElementNS(XML_p
, XML_presentation
);
469 mPresentationFS
->endDocument();
470 mPresentationFS
.reset();
471 // Free all FSHelperPtr, to flush data before committing storage
472 for (auto& serializer
: mpSlidesFSArray
)
476 serializer
->endDocument();
478 mpSlidesFSArray
.clear();
482 rGraphicExportCache
.pop();
491 ::oox::ole::VbaProject
* PowerPointExport::implCreateVbaProject() const
493 return new ::oox::ole::VbaProject(getComponentContext(), getModel(), u
"Impress");
496 void PowerPointExport::WriteCustomSlideShow()
498 Reference
<XCustomPresentationSupplier
> aXCPSup(mXModel
, css::uno::UNO_QUERY
);
499 if (!aXCPSup
.is() || !aXCPSup
->getCustomPresentations()->hasElements())
502 mPresentationFS
->startElementNS(XML_p
, XML_custShowLst
);
504 Reference
<XDrawPagesSupplier
> xDPS(getModel(), uno::UNO_QUERY_THROW
);
505 Reference
<XDrawPages
> xDrawPages(xDPS
->getDrawPages(), uno::UNO_SET_THROW
);
506 Reference
<XNameContainer
> aXNameCont(aXCPSup
->getCustomPresentations());
507 const Sequence
<OUString
> aNameSeq(aXNameCont
->getElementNames());
510 sal_uInt32 nCustomShowIndex
= 0;
511 sal_Int32 nSlideCount
= xDrawPages
->getCount();
513 for (OUString
const& customShowName
: aNameSeq
)
515 mPresentationFS
->startElementNS(XML_p
, XML_custShow
, XML_name
, customShowName
, XML_id
,
516 OUString::number(nCustomShowIndex
++));
518 mAny
= aXNameCont
->getByName(customShowName
);
519 Reference
<XIndexContainer
> aXIContainer
;
520 if (mAny
>>= aXIContainer
)
522 mPresentationFS
->startElementNS(XML_p
, XML_sldLst
);
524 sal_Int32 nCustomShowSlideCount
= aXIContainer
->getCount();
525 for (sal_Int32 i
= 0; i
< nCustomShowSlideCount
; ++i
)
527 Reference
<XDrawPage
> aXCustomShowDrawPage
;
528 aXIContainer
->getByIndex(i
) >>= aXCustomShowDrawPage
;
529 Reference
<XNamed
> aXName(aXCustomShowDrawPage
, UNO_QUERY_THROW
);
530 OUString sCustomShowSlideName
= aXName
->getName();
532 for (sal_Int32 j
= 0; j
< nSlideCount
; ++j
)
534 Reference
<XDrawPage
> xDrawPage
;
535 xDrawPages
->getByIndex(j
) >>= xDrawPage
;
536 Reference
<XNamed
> xNamed(xDrawPage
, UNO_QUERY_THROW
);
537 OUString sSlideName
= xNamed
->getName();
539 if (sCustomShowSlideName
== sSlideName
)
545 mPresentationFS
->singleElementNS(XML_p
, XML_sld
, FSNS(XML_r
, XML_id
), sRelId
);
547 mPresentationFS
->endElementNS(XML_p
, XML_sldLst
);
549 mPresentationFS
->endElementNS(XML_p
, XML_custShow
);
551 mPresentationFS
->endElementNS(XML_p
, XML_custShowLst
);
554 void PowerPointExport::ImplWriteBackground(const FSHelperPtr
& pFS
, const Reference
< XPropertySet
>& rXPropSet
)
556 FillStyle
aFillStyle(FillStyle_NONE
);
557 if (ImplGetPropertyValue(rXPropSet
, u
"FillStyle"_ustr
))
560 if (aFillStyle
== FillStyle_NONE
||
561 aFillStyle
== FillStyle_HATCH
)
564 pFS
->startElementNS(XML_p
, XML_bg
);
565 pFS
->startElementNS(XML_p
, XML_bgPr
);
567 PowerPointShapeExport
aDML(pFS
, &maShapeMap
, this);
568 aDML
.SetBackgroundDark(mbIsBackgroundDark
);
569 aDML
.WriteFill(rXPropSet
, maPageSize
);
571 pFS
->endElementNS(XML_p
, XML_bgPr
);
572 pFS
->endElementNS(XML_p
, XML_bg
);
577 <p:cNvPr id=\"1\" name=\"\"/>\
583 <a:off x=\"0\" y=\"0\"/>\
584 <a:ext cx=\"0\" cy=\"0\"/>\
585 <a:chOff x=\"0\" y=\"0\"/>\
586 <a:chExt cx=\"0\" cy=\"0\"/>\
590 const char* PowerPointExport::GetSideDirection(sal_uInt8 nDirection
)
592 const char* pDirection
= nullptr;
613 const char* PowerPointExport::GetCornerDirection(sal_uInt8 nDirection
)
615 const char* pDirection
= nullptr;
636 const char* PowerPointExport::Get8Direction(sal_uInt8 nDirection
)
638 const char* pDirection
= GetSideDirection(nDirection
);
641 pDirection
= GetCornerDirection(nDirection
);
646 void PowerPointExport::WriteTransition(const FSHelperPtr
& pFS
)
648 FadeEffect eFadeEffect
= FadeEffect_NONE
;
649 if (ImplGetPropertyValue(mXPagePropSet
, u
"Effect"_ustr
))
650 mAny
>>= eFadeEffect
;
652 sal_Int16 nTransitionType
= 0, nTransitionSubtype
= 0;
653 sal_Int8 nPPTTransitionType
= 0;
654 sal_uInt8 nDirection
= 0;
657 OUString sSoundRelId
;
660 if (ImplGetPropertyValue(mXPagePropSet
, u
"TransitionType"_ustr
) && (mAny
>>= nTransitionType
) &&
661 ImplGetPropertyValue(mXPagePropSet
, u
"TransitionSubtype"_ustr
) && (mAny
>>= nTransitionSubtype
))
663 // FADEOVERCOLOR with black -> fade, with white -> flash
664 sal_Int32 nTransitionFadeColor
= 0;
665 if( ImplGetPropertyValue(mXPagePropSet
, u
"TransitionFadeColor"_ustr
))
666 mAny
>>= nTransitionFadeColor
;
667 nPPTTransitionType
= GetTransition(nTransitionType
, nTransitionSubtype
, eFadeEffect
, nTransitionFadeColor
, nDirection
);
670 if (!nPPTTransitionType
&& eFadeEffect
!= FadeEffect_NONE
)
671 nPPTTransitionType
= GetTransition(eFadeEffect
, nDirection
);
673 if (ImplGetPropertyValue(mXPagePropSet
, u
"Sound"_ustr
) && (mAny
>>= sSoundUrl
))
674 embedEffectAudio(pFS
, sSoundUrl
, sSoundRelId
, sSoundName
);
676 bool bOOXmlSpecificTransition
= false;
678 sal_Int32 nTransition
= 0;
679 const char* pDirection
= nullptr;
680 const char* pOrientation
= nullptr;
681 const char* pThruBlk
= nullptr;
682 const char* pSpokes
= nullptr;
684 char pSpokesTmp
[2] = "0";
687 sal_Int32 nTransition14
= 0;
688 const char* pDirection14
= nullptr;
689 const char* pInverted
= nullptr;
690 const char* pPattern
= nullptr; // diamond or hexagon
693 const char* pPresetTransition
= nullptr;
695 if (!nPPTTransitionType
)
697 switch (nTransitionType
)
699 case animations::TransitionType::BARWIPE
:
701 if (nTransitionSubtype
== animations::TransitionSubType::FADEOVERCOLOR
)
703 nTransition
= XML_cut
;
705 bOOXmlSpecificTransition
= true;
709 case animations::TransitionType::MISCSHAPEWIPE
:
711 switch (nTransitionSubtype
)
713 case animations::TransitionSubType::TOPTOBOTTOM
: // Turn around
714 nTransition
= XML_fade
;
715 nTransition14
= XML_flip
;
717 bOOXmlSpecificTransition
= true;
719 case animations::TransitionSubType::BOTTOMRIGHT
: // Rochade
720 nTransition
= XML_fade
;
721 nTransition14
= XML_switch
;
723 bOOXmlSpecificTransition
= true;
725 case animations::TransitionSubType::VERTICAL
: // Vortex
726 nTransition
= XML_fade
;
727 nTransition14
= XML_vortex
;
728 bOOXmlSpecificTransition
= true;
730 case animations::TransitionSubType::HORIZONTAL
: // Ripple
731 nTransition
= XML_fade
;
732 nTransition14
= XML_ripple
;
733 bOOXmlSpecificTransition
= true;
735 case animations::TransitionSubType::LEFTTORIGHT
: // Fall
736 nTransition
= XML_fade
;
737 pPresetTransition
= "fallOver";
738 bOOXmlSpecificTransition
= true;
740 case animations::TransitionSubType::CORNERSIN
: // Inside turning cube
743 case animations::TransitionSubType::CORNERSOUT
: // Outside turning cube
744 nTransition
= XML_fade
;
745 nTransition14
= XML_prism
;
746 bOOXmlSpecificTransition
= true;
748 case animations::TransitionSubType::DIAMOND
: // Glitter
749 nTransition
= XML_fade
;
750 nTransition14
= XML_glitter
;
752 pPattern
= "hexagon";
753 bOOXmlSpecificTransition
= true;
755 case animations::TransitionSubType::HEART
: // Honeycomb
756 nTransition
= XML_fade
;
757 nTransition14
= XML_honeycomb
;
758 bOOXmlSpecificTransition
= true;
766 AnimationSpeed animationSpeed
= AnimationSpeed_MEDIUM
;
767 const char* speed
= nullptr;
768 sal_Int32 advanceTiming
= -1;
769 sal_Int32 changeType
= 0;
771 sal_Int32 nTransitionDuration
= -1;
772 bool isTransitionDurationSet
= false;
774 // try to use TransitionDuration instead of old Speed property
775 if (ImplGetPropertyValue(mXPagePropSet
, u
"TransitionDuration"_ustr
))
777 double fTransitionDuration
= -1.0;
778 mAny
>>= fTransitionDuration
;
779 if (fTransitionDuration
>= 0)
781 nTransitionDuration
= fTransitionDuration
* 1000.0;
783 // override values because in MS formats meaning of fast/medium/slow is different
784 if (nTransitionDuration
<= 500)
789 else if (nTransitionDuration
>= 1000)
798 bool isStandardValue
= nTransitionDuration
== 500
799 || nTransitionDuration
== 750
800 || nTransitionDuration
== 1000;
803 isTransitionDurationSet
= true;
806 else if (ImplGetPropertyValue(mXPagePropSet
, u
"Speed"_ustr
))
808 mAny
>>= animationSpeed
;
810 switch (animationSpeed
)
813 case AnimationSpeed_MEDIUM
:
816 case AnimationSpeed_SLOW
:
819 case AnimationSpeed_FAST
:
824 // check if we resolved what transition to export or time is set
825 if (!nPPTTransitionType
&& !bOOXmlSpecificTransition
&& !isTransitionDurationSet
)
828 if (ImplGetPropertyValue(mXPagePropSet
, u
"Change"_ustr
))
831 // 1 means automatic, 2 half automatic - not sure what it means - at least I don't see it in UI
832 if (changeType
== 1 && ImplGetPropertyValue(mXPagePropSet
, u
"Duration"_ustr
))
833 mAny
>>= advanceTiming
;
835 if (!bOOXmlSpecificTransition
)
837 switch (nPPTTransitionType
)
839 case PPT_TRANSITION_TYPE_BLINDS
:
840 nTransition
= XML_blinds
;
841 pDirection
= (nDirection
== 0) ? "vert" : "horz";
843 case PPT_TRANSITION_TYPE_CHECKER
:
844 nTransition
= XML_checker
;
845 pDirection
= (nDirection
== 1) ? "vert" : "horz";
847 case PPT_TRANSITION_TYPE_CIRCLE
:
848 nTransition
= XML_circle
;
850 case PPT_TRANSITION_TYPE_COMB
:
851 nTransition
= XML_comb
;
852 pDirection
= (nDirection
== 1) ? "vert" : "horz";
854 case PPT_TRANSITION_TYPE_COVER
:
855 nTransition
= XML_cover
;
856 pDirection
= Get8Direction(nDirection
);
858 case PPT_TRANSITION_TYPE_DIAMOND
:
859 nTransition
= XML_diamond
;
861 case PPT_TRANSITION_TYPE_DISSOLVE
:
862 nTransition
= XML_dissolve
;
864 case PPT_TRANSITION_TYPE_FADE
:
865 nTransition
= XML_fade
;
868 case PPT_TRANSITION_TYPE_SMOOTHFADE
:
869 nTransition
= XML_fade
;
871 case PPT_TRANSITION_TYPE_NEWSFLASH
:
872 nTransition
= XML_newsflash
;
874 case PPT_TRANSITION_TYPE_PLUS
:
875 nTransition
= XML_plus
;
877 case PPT_TRANSITION_TYPE_PULL
:
878 nTransition
= XML_pull
;
879 pDirection
= Get8Direction(nDirection
);
881 case PPT_TRANSITION_TYPE_PUSH
:
882 nTransition
= XML_push
;
883 pDirection
= GetSideDirection(nDirection
);
885 case PPT_TRANSITION_TYPE_RANDOM
:
886 nTransition
= XML_random
;
888 case PPT_TRANSITION_TYPE_RANDOM_BARS
:
889 nTransition
= XML_randomBar
;
890 pDirection
= (nDirection
== 1) ? "vert" : "horz";
892 case PPT_TRANSITION_TYPE_SPLIT
:
893 nTransition
= XML_split
;
894 pDirection
= (nDirection
& 1) ? "in" : "out";
895 pOrientation
= (nDirection
< 2) ? "horz" : "vert";
897 case PPT_TRANSITION_TYPE_STRIPS
:
898 nTransition
= XML_strips
;
899 pDirection
= GetCornerDirection(nDirection
);
901 case PPT_TRANSITION_TYPE_WEDGE
:
902 nTransition
= XML_wedge
;
904 case PPT_TRANSITION_TYPE_WHEEL
:
905 nTransition
= XML_wheel
;
906 if (nDirection
!= 4 && nDirection
<= 9)
908 pSpokesTmp
[0] = '0' + nDirection
;
909 pSpokes
= pSpokesTmp
;
912 case PPT_TRANSITION_TYPE_WIPE
:
913 nTransition
= XML_wipe
;
914 pDirection
= GetSideDirection(nDirection
);
916 case PPT_TRANSITION_TYPE_ZOOM
:
917 nTransition
= XML_zoom
;
918 pDirection
= (nDirection
== 1) ? "in" : "out";
920 case PPT_TRANSITION_TYPE_FLASH
:
921 nTransition14
= XML_flash
;
922 nTransition
= XML_fade
;
923 bOOXmlSpecificTransition
= true;
925 // coverity[dead_error_line] - following conditions exist to avoid compiler warning
926 case PPT_TRANSITION_TYPE_NONE
:
933 bool isAdvanceTimingSet
= advanceTiming
!= -1;
934 if (nTransition14
|| pPresetTransition
|| isTransitionDurationSet
)
936 const char* pRequiresNS
= (nTransition14
|| isTransitionDurationSet
) ? "p14" : "p15";
938 pFS
->startElement(FSNS(XML_mc
, XML_AlternateContent
));
939 pFS
->startElement(FSNS(XML_mc
, XML_Choice
), XML_Requires
, pRequiresNS
);
941 if(isTransitionDurationSet
&& isAdvanceTimingSet
)
943 pFS
->startElementNS(XML_p
, XML_transition
,
945 XML_advTm
, OString::number(advanceTiming
* 1000),
946 FSNS(XML_p14
, XML_dur
), OString::number(nTransitionDuration
));
948 else if(isTransitionDurationSet
)
950 pFS
->startElementNS(XML_p
, XML_transition
,
952 FSNS(XML_p14
, XML_dur
), OString::number(nTransitionDuration
));
954 else if(isAdvanceTimingSet
)
956 pFS
->startElementNS(XML_p
, XML_transition
,
958 XML_advTm
, OString::number(advanceTiming
* 1000));
962 pFS
->startElementNS(XML_p
, XML_transition
, XML_spd
, speed
);
967 pFS
->singleElementNS(XML_p14
, nTransition14
,
968 XML_isInverted
, pInverted
,
969 XML_dir
, pDirection14
,
970 XML_pattern
, pPattern
);
972 else if (pPresetTransition
)
974 pFS
->singleElementNS(XML_p15
, XML_prstTrans
,
975 XML_prst
, pPresetTransition
);
977 else if (isTransitionDurationSet
&& nTransition
)
979 pFS
->singleElementNS(XML_p
, nTransition
,
981 XML_orient
, pOrientation
,
983 XML_thruBlk
, pThruBlk
);
986 if (!sSoundRelId
.isEmpty())
987 WriteSndAc(pFS
, sSoundRelId
, sSoundName
);
989 pFS
->endElement(FSNS(XML_p
, XML_transition
));
991 pFS
->endElement(FSNS(XML_mc
, XML_Choice
));
992 pFS
->startElement(FSNS(XML_mc
, XML_Fallback
));
995 pFS
->startElementNS(XML_p
, XML_transition
,
997 XML_advTm
, sax_fastparser::UseIf(OString::number(advanceTiming
* 1000), isAdvanceTimingSet
));
1001 pFS
->singleElementNS(XML_p
, nTransition
,
1002 XML_dir
, pDirection
,
1003 XML_orient
, pOrientation
,
1004 XML_spokes
, pSpokes
,
1005 XML_thruBlk
, pThruBlk
);
1008 if (!sSoundRelId
.isEmpty())
1009 WriteSndAc(pFS
, sSoundRelId
, sSoundName
);
1011 pFS
->endElementNS(XML_p
, XML_transition
);
1013 if (nTransition14
|| pPresetTransition
|| isTransitionDurationSet
)
1015 pFS
->endElement(FSNS(XML_mc
, XML_Fallback
));
1016 pFS
->endElement(FSNS(XML_mc
, XML_AlternateContent
));
1020 void PowerPointExport::WriteAuthors()
1022 if (maAuthors
.empty())
1025 FSHelperPtr pFS
= openFragmentStreamWithSerializer(u
"ppt/commentAuthors.xml"_ustr
,
1026 u
"application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml"_ustr
);
1027 addRelation(mPresentationFS
->getOutputStream(),
1028 oox::getRelationship(Relationship::COMMENTAUTHORS
),
1029 u
"commentAuthors.xml");
1031 pFS
->startElementNS(XML_p
, XML_cmAuthorLst
,
1032 FSNS(XML_xmlns
, XML_p
), getNamespaceURL(OOX_NS(ppt
)));
1034 for (const AuthorsMap::value_type
& i
: maAuthors
)
1036 pFS
->singleElementNS(XML_p
, XML_cmAuthor
,
1037 XML_id
, OString::number(i
.second
.nId
),
1039 XML_initials
, i
.second
.sInitials
,
1040 XML_lastIdx
, OString::number(i
.second
.nLastIndex
),
1041 XML_clrIdx
, OString::number(i
.second
.nId
));
1044 pFS
->endElementNS(XML_p
, XML_cmAuthorLst
);
1049 sal_Int32
PowerPointExport::GetAuthorIdAndLastIndex(const OUString
& sAuthor
,
1050 const OUString
& sInitials
,
1051 sal_Int32
& nLastIndex
)
1053 if (maAuthors
.count(sAuthor
) <= 0)
1054 maAuthors
.emplace(sAuthor
, AuthorComments(maAuthors
.size(), 0, sInitials
));
1056 nLastIndex
= ++maAuthors
[ sAuthor
].nLastIndex
;
1058 return maAuthors
[ sAuthor
].nId
;
1061 void PowerPointExport::WritePresentationProps()
1063 Reference
<XPresentationSupplier
> xPresentationSupplier(mXModel
, uno::UNO_QUERY
);
1064 if (!xPresentationSupplier
.is())
1067 Reference
<beans::XPropertySet
> xPresentationProps(xPresentationSupplier
->getPresentation(),
1069 bool bEndlessVal
= xPresentationProps
->getPropertyValue(u
"IsEndless"_ustr
).get
<bool>();
1070 bool bChangeManually
= xPresentationProps
->getPropertyValue(u
"IsAutomatic"_ustr
).get
<bool>();
1071 OUString sFirstPage
= xPresentationProps
->getPropertyValue(u
"FirstPage"_ustr
).get
<OUString
>();
1072 OUString sCustomShow
= xPresentationProps
->getPropertyValue(u
"CustomShow"_ustr
).get
<OUString
>();
1074 FSHelperPtr pFS
= openFragmentStreamWithSerializer(
1075 u
"ppt/presProps.xml"_ustr
,
1076 u
"application/vnd.openxmlformats-officedocument.presentationml.presProps+xml"_ustr
);
1078 addRelation(mPresentationFS
->getOutputStream(),
1079 oox::getRelationship(Relationship::PRESPROPS
), u
"presProps.xml");
1081 pFS
->startElementNS(XML_p
, XML_presentationPr
, PPRNMSS
);
1083 pFS
->startElementNS(XML_p
, XML_showPr
, XML_loop
, sax_fastparser::UseIf("1", bEndlessVal
),
1084 XML_useTimings
, sax_fastparser::UseIf("0", bChangeManually
),
1085 XML_showNarration
, "1");
1087 Reference
<drawing::XDrawPagesSupplier
> xDPS(mXModel
, uno::UNO_QUERY_THROW
);
1088 Reference
<drawing::XDrawPages
> xDrawPages(xDPS
->getDrawPages(), uno::UNO_SET_THROW
);
1089 if (!sFirstPage
.isEmpty())
1091 sal_Int32 nStartSlide
= 1;
1092 sal_Int32 nEndSlide
= xDrawPages
->getCount();
1093 for (sal_Int32 i
= 0; i
< nEndSlide
; i
++)
1095 Reference
<drawing::XDrawPage
> xDrawPage
;
1096 xDrawPages
->getByIndex(i
) >>= xDrawPage
;
1097 Reference
<container::XNamed
> xNamed(xDrawPage
, uno::UNO_QUERY_THROW
);
1098 if (xNamed
->getName() == sFirstPage
)
1100 nStartSlide
= i
+ 1;
1105 pFS
->singleElementNS(XML_p
, XML_sldRg
, XML_st
, OUString::number(nStartSlide
), XML_end
,
1106 OUString::number(nEndSlide
));
1109 if (!sCustomShow
.isEmpty())
1111 css::uno::Reference
<css::presentation::XCustomPresentationSupplier
>
1112 XCustPresentationSupplier(mXModel
, css::uno::UNO_QUERY_THROW
);
1113 css::uno::Reference
<css::container::XNameContainer
> mxCustShows
;
1114 mxCustShows
= XCustPresentationSupplier
->getCustomPresentations();
1115 const css::uno::Sequence
<OUString
> aNameSeq(mxCustShows
->getElementNames());
1117 sal_Int32 nCustShowIndex
= 0;
1118 for (sal_Int32 i
= 0; i
< aNameSeq
.getLength(); i
++)
1120 if (aNameSeq
[i
] == sCustomShow
)
1127 pFS
->singleElementNS(XML_p
, XML_custShow
, XML_id
, OUString::number(nCustShowIndex
));
1130 pFS
->endElementNS(XML_p
, XML_showPr
);
1132 pFS
->endElementNS(XML_p
, XML_presentationPr
);
1137 bool PowerPointExport::WriteComments(sal_uInt32 nPageNum
)
1139 Reference
< XAnnotationAccess
> xAnnotationAccess(mXDrawPage
, uno::UNO_QUERY
);
1140 if (xAnnotationAccess
.is())
1142 Reference
< XAnnotationEnumeration
> xAnnotationEnumeration(xAnnotationAccess
->createAnnotationEnumeration());
1144 if (xAnnotationEnumeration
->hasMoreElements())
1146 bool bRemoveCommentAuthorDates
1147 = SvtSecurityOptions::IsOptionSet(
1148 SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo
)
1149 && !SvtSecurityOptions::IsOptionSet(
1150 SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo
);
1152 FSHelperPtr pFS
= openFragmentStreamWithSerializer(
1153 "ppt/comments/comment" + OUString::number(nPageNum
+ 1) + ".xml",
1154 u
"application/vnd.openxmlformats-officedocument.presentationml.comments+xml"_ustr
);
1156 pFS
->startElementNS(XML_p
, XML_cmLst
,
1157 FSNS(XML_xmlns
, XML_p
), this->getNamespaceURL(OOX_NS(ppt
)));
1161 Reference
< XAnnotation
> xAnnotation(xAnnotationEnumeration
->nextElement());
1162 util::DateTime
aDateTime(xAnnotation
->getDateTime());
1163 RealPoint2D
aRealPoint2D(xAnnotation
->getPosition());
1164 Reference
< XText
> xText(xAnnotation
->getTextRange());
1165 sal_Int32 nLastIndex
;
1166 OUString
sAuthor(bRemoveCommentAuthorDates
1168 + OUString::number(GetInfoID(xAnnotation
->getAuthor()))
1169 : xAnnotation
->getAuthor());
1170 OUString
sInitials(bRemoveCommentAuthorDates
1171 ? "A" + OUString::number(GetInfoID(xAnnotation
->getAuthor()))
1172 : xAnnotation
->getInitials());
1173 sal_Int32 nId
= GetAuthorIdAndLastIndex(sAuthor
, sInitials
, nLastIndex
);
1174 char cDateTime
[sizeof("-32768-65535-65535T65535:65535:65535.4294967295")];
1175 // reserve enough space for hypothetical max length
1177 snprintf(cDateTime
, sizeof cDateTime
, "%02" SAL_PRIdINT32
"-%02" SAL_PRIuUINT32
"-%02" SAL_PRIuUINT32
"T%02" SAL_PRIuUINT32
":%02" SAL_PRIuUINT32
":%02" SAL_PRIuUINT32
".%09" SAL_PRIuUINT32
, sal_Int32(aDateTime
.Year
), sal_uInt32(aDateTime
.Month
), sal_uInt32(aDateTime
.Day
), sal_uInt32(aDateTime
.Hours
), sal_uInt32(aDateTime
.Minutes
), sal_uInt32(aDateTime
.Seconds
), aDateTime
.NanoSeconds
);
1179 util::DateTime aEmptyDate
;
1180 if (bRemoveCommentAuthorDates
|| aDateTime
== aEmptyDate
)
1182 pFS
->startElementNS(XML_p
, XML_cm
,
1183 XML_authorId
, OString::number(nId
),
1184 XML_idx
, OString::number(nLastIndex
));
1188 pFS
->startElementNS(XML_p
, XML_cm
,
1189 XML_authorId
, OString::number(nId
),
1191 XML_idx
, OString::number(nLastIndex
));
1194 pFS
->singleElementNS(XML_p
, XML_pos
,
1195 XML_x
, OString::number(std::round(convertMm100ToMasterUnit(aRealPoint2D
.X
* 100))),
1196 XML_y
, OString::number(std::round(convertMm100ToMasterUnit(aRealPoint2D
.Y
* 100))));
1198 pFS
->startElementNS(XML_p
, XML_text
);
1199 pFS
->write(xText
->getString());
1200 pFS
->endElementNS(XML_p
, XML_text
);
1202 pFS
->endElementNS(XML_p
, XML_cm
);
1205 while (xAnnotationEnumeration
->hasMoreElements());
1207 pFS
->endElementNS(XML_p
, XML_cmLst
);
1218 void PowerPointExport::WriteVBA()
1223 uno::Reference
<document::XStorageBasedDocument
> xStorageBasedDocument(getModel(), uno::UNO_QUERY
);
1224 if (!xStorageBasedDocument
.is())
1227 uno::Reference
<embed::XStorage
> xDocumentStorage
= xStorageBasedDocument
->getDocumentStorage();
1228 OUString
aMacrosName(u
"_MS_VBA_Macros"_ustr
);
1229 if (!xDocumentStorage
.is() || !xDocumentStorage
->hasByName(aMacrosName
))
1232 const sal_Int32 nOpenMode
= embed::ElementModes::READ
;
1233 uno::Reference
<io::XInputStream
> xMacrosStream(xDocumentStorage
->openStreamElement(aMacrosName
, nOpenMode
), uno::UNO_QUERY
);
1234 if (!xMacrosStream
.is())
1237 uno::Reference
<io::XOutputStream
> xOutputStream
= openFragmentStream(u
"ppt/vbaProject.bin"_ustr
, u
"application/vnd.ms-office.vbaProject"_ustr
);
1238 comphelper::OStorageHelper::CopyInputToOutput(xMacrosStream
, xOutputStream
);
1240 // Write the relationship.
1241 addRelation(mPresentationFS
->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT
), u
"vbaProject.bin");
1244 void PowerPointExport::WriteModifyVerifier()
1246 Sequence
<PropertyValue
> aInfo
;
1250 Reference
<lang::XMultiServiceFactory
> xFactory(mXModel
, UNO_QUERY
);
1251 Reference
<XPropertySet
> xDocSettings(
1252 xFactory
->createInstance(u
"com.sun.star.document.Settings"_ustr
), UNO_QUERY
);
1253 xDocSettings
->getPropertyValue(u
"ModifyPasswordInfo"_ustr
) >>= aInfo
;
1255 catch (const Exception
&)
1259 if (aInfo
.hasElements())
1261 OUString sAlgorithm
, sSalt
, sHash
;
1262 sal_Int32 nCount
= 0;
1263 for (auto& prop
: aInfo
)
1265 if (prop
.Name
== "algorithm-name")
1266 prop
.Value
>>= sAlgorithm
;
1267 else if (prop
.Name
== "salt")
1268 prop
.Value
>>= sSalt
;
1269 else if (prop
.Name
== "iteration-count")
1270 prop
.Value
>>= nCount
;
1271 else if (prop
.Name
== "hash")
1272 prop
.Value
>>= sHash
;
1274 if (!sAlgorithm
.isEmpty() && !sSalt
.isEmpty() && !sHash
.isEmpty())
1276 sal_Int32 nAlgorithmSid
= 0;
1277 if (sAlgorithm
== "MD2")
1279 else if (sAlgorithm
== "MD4")
1281 else if (sAlgorithm
== "MD5")
1283 else if (sAlgorithm
== "SHA-1")
1285 else if (sAlgorithm
== "MAC")
1287 else if (sAlgorithm
== "RIPEMD")
1289 else if (sAlgorithm
== "RIPEMD-160")
1291 else if (sAlgorithm
== "HMAC")
1293 else if (sAlgorithm
== "SHA-256")
1295 else if (sAlgorithm
== "SHA-384")
1297 else if (sAlgorithm
== "SHA-512")
1300 if (nAlgorithmSid
!= 0)
1301 mPresentationFS
->singleElementNS(XML_p
, XML_modifyVerifier
,
1302 XML_cryptProviderType
, "rsaAES",
1303 XML_cryptAlgorithmClass
, "hash",
1304 XML_cryptAlgorithmType
, "typeAny",
1305 XML_cryptAlgorithmSid
, OString::number(nAlgorithmSid
),
1306 XML_spinCount
, OString::number(nCount
),
1307 XML_saltData
, sSalt
,
1308 XML_hashData
, sHash
);
1313 void PowerPointExport::ImplWriteSlide(sal_uInt32 nPageNum
, sal_uInt32 nMasterNum
, sal_uInt16
/* nMode */,
1314 bool bHasBackground
, Reference
< XPropertySet
> const& aXBackgroundPropSet
)
1316 SAL_INFO("sd.eppt", "write slide: " << nPageNum
<< "\n----------------");
1320 mPresentationFS
->startElementNS(XML_p
, XML_sldIdLst
);
1322 // add explicit relation of presentation to this slide
1323 OUString sRelId
= addRelation(mPresentationFS
->getOutputStream(),
1324 oox::getRelationship(Relationship::SLIDE
),
1325 Concat2View("slides/slide" + OUString::number(nPageNum
+ 1) +".xml"));
1327 mPresentationFS
->singleElementNS(XML_p
, XML_sldId
,
1328 XML_id
, OString::number(GetNewSlideId()),
1329 FSNS(XML_r
, XML_id
), sRelId
);
1331 maRelId
.push_back(sRelId
);
1333 if (nPageNum
== mnPages
- 1)
1334 mPresentationFS
->endElementNS(XML_p
, XML_sldIdLst
);
1336 FSHelperPtr pFS
= openFragmentStreamWithSerializer(
1337 "ppt/slides/slide" + OUString::number(nPageNum
+ 1) + ".xml",
1338 u
"application/vnd.openxmlformats-officedocument.presentationml.slide+xml"_ustr
);
1340 if (mpSlidesFSArray
.size() < mnPages
)
1341 mpSlidesFSArray
.resize(mnPages
);
1342 mpSlidesFSArray
[ nPageNum
] = pFS
;
1344 const char* pShow
= nullptr;
1345 const char* pShowMasterShape
= nullptr;
1347 if (ImplGetPropertyValue(mXPagePropSet
, u
"Visible"_ustr
))
1350 if ((mAny
>>= bShow
) && !bShow
)
1354 if (ImplGetPropertyValue(mXPagePropSet
, u
"IsBackgroundObjectsVisible"_ustr
))
1356 bool bShowMasterShape(false);
1357 if ((mAny
>>= bShowMasterShape
) && !bShowMasterShape
)
1358 pShowMasterShape
= "0";
1361 pFS
->startElementNS(XML_p
, XML_sld
, PNMSS
, XML_show
, pShow
, XML_showMasterSp
, pShowMasterShape
);
1363 pFS
->startElementNS(XML_p
, XML_cSld
);
1368 ImplWriteBackground(pFS
, aXBackgroundPropSet
);
1371 WriteShapeTree(pFS
, NORMAL
, false);
1373 pFS
->endElementNS(XML_p
, XML_cSld
);
1375 WriteTransition(pFS
);
1376 WriteAnimations(pFS
, mXDrawPage
, *this);
1378 pFS
->endElementNS(XML_p
, XML_sld
);
1380 // add implicit relation to slide layout
1381 addRelation(pFS
->getOutputStream(),
1382 oox::getRelationship(Relationship::SLIDELAYOUT
),
1383 Concat2View("../slideLayouts/slideLayout" +
1384 OUString::number(GetLayoutFileId(GetLayoutOffset(mXPagePropSet
), nMasterNum
)) +
1387 if (WriteComments(nPageNum
))
1388 // add implicit relation to slide comments
1389 addRelation(pFS
->getOutputStream(),
1390 oox::getRelationship(Relationship::COMMENTS
),
1391 Concat2View("../comments/comment" + OUString::number(nPageNum
+ 1) + ".xml"));
1393 SAL_INFO("sd.eppt", "----------------");
1396 void PowerPointExport::ImplWriteNotes(sal_uInt32 nPageNum
)
1398 if (!mbCreateNotes
|| !ContainsOtherShapeThanPlaceholders())
1401 SAL_INFO("sd.eppt", "write Notes " << nPageNum
<< "\n----------------");
1403 FSHelperPtr pFS
= openFragmentStreamWithSerializer(
1404 "ppt/notesSlides/notesSlide" +
1405 OUString::number(nPageNum
+ 1) +
1407 u
"application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml"_ustr
);
1409 pFS
->startElementNS(XML_p
, XML_notes
, PNMSS
);
1411 pFS
->startElementNS(XML_p
, XML_cSld
);
1413 WriteShapeTree(pFS
, NOTICE
, false);
1415 pFS
->endElementNS(XML_p
, XML_cSld
);
1417 pFS
->endElementNS(XML_p
, XML_notes
);
1419 // add implicit relation to slide
1420 addRelation(pFS
->getOutputStream(),
1421 oox::getRelationship(Relationship::SLIDE
),
1422 Concat2View("../slides/slide" + OUString::number(nPageNum
+ 1) + ".xml"));
1424 // add slide implicit relation to notes
1425 if (nPageNum
< mpSlidesFSArray
.size())
1426 addRelation(mpSlidesFSArray
[ nPageNum
]->getOutputStream(),
1427 oox::getRelationship(Relationship::NOTESSLIDE
),
1428 Concat2View("../notesSlides/notesSlide" + OUString::number(nPageNum
+ 1) + ".xml"));
1430 // add implicit relation to notes master
1431 addRelation(pFS
->getOutputStream(),
1432 oox::getRelationship(Relationship::NOTESMASTER
),
1433 u
"../notesMasters/notesMaster1.xml");
1435 SAL_INFO("sd.eppt", "-----------------");
1440 void PowerPointExport::AddLayoutIdAndRelation(const FSHelperPtr
& pFS
, sal_Int32 nLayoutFileId
)
1442 // add implicit relation of slide master to slide layout
1443 OUString sRelId
= addRelation(pFS
->getOutputStream(),
1444 oox::getRelationship(Relationship::SLIDELAYOUT
),
1445 Concat2View("../slideLayouts/slideLayout" + OUString::number(nLayoutFileId
) + ".xml"));
1447 pFS
->singleElementNS(XML_p
, XML_sldLayoutId
,
1448 XML_id
, OString::number(GetNewSlideMasterId()),
1449 FSNS(XML_r
, XML_id
), sRelId
);
1452 void PowerPointExport::ImplWriteSlideMaster(sal_uInt32 nPageNum
, Reference
< XPropertySet
> const& aXBackgroundPropSet
)
1454 SAL_INFO("sd.eppt", "write master slide: " << nPageNum
<< "\n--------------");
1458 mPresentationFS
->startElementNS(XML_p
, XML_sldMasterIdLst
);
1460 OUString sRelId
= addRelation(mPresentationFS
->getOutputStream(),
1461 oox::getRelationship(Relationship::SLIDEMASTER
),
1462 Concat2View("slideMasters/slideMaster" + OUString::number(nPageNum
+ 1) + ".xml"));
1464 mPresentationFS
->singleElementNS(XML_p
, XML_sldMasterId
,
1465 XML_id
, OString::number(GetNewSlideMasterId()),
1466 FSNS(XML_r
, XML_id
), sRelId
);
1468 if (nPageNum
== mnMasterPages
- 1)
1469 mPresentationFS
->endElementNS(XML_p
, XML_sldMasterIdLst
);
1472 openFragmentStreamWithSerializer("ppt/slideMasters/slideMaster" +
1473 OUString::number(nPageNum
+ 1) + ".xml",
1474 u
"application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml"_ustr
);
1476 SdrPage
* pMasterPage
= SdPage::getImplementation(mXDrawPage
);
1477 model::Theme
* pTheme
= nullptr;
1480 pTheme
= pMasterPage
->getSdrPageProperties().getTheme().get();
1483 // write theme per master
1484 WriteTheme(nPageNum
, pTheme
);
1486 // add implicit relation to the presentation theme
1487 addRelation(pFS
->getOutputStream(),
1488 oox::getRelationship(Relationship::THEME
),
1489 Concat2View("../theme/theme" + OUString::number(nPageNum
+ 1) + ".xml"));
1491 pFS
->startElementNS(XML_p
, XML_sldMaster
, PNMSS
);
1493 pFS
->startElementNS(XML_p
, XML_cSld
);
1495 if (aXBackgroundPropSet
)
1496 ImplWriteBackground(pFS
, aXBackgroundPropSet
);
1497 WriteShapeTree(pFS
, MASTER
, true);
1499 pFS
->endElementNS(XML_p
, XML_cSld
);
1501 css::uno::Reference
< css::beans::XPropertySet
> xDocPropSet(getModel(), uno::UNO_QUERY
);
1502 if (xDocPropSet
.is())
1504 uno::Sequence
<beans::PropertyValue
> aGrabBag
;
1505 if (xDocPropSet
->getPropertySetInfo()->hasPropertyByName(u
"InteropGrabBag"_ustr
))
1506 xDocPropSet
->getPropertyValue(u
"InteropGrabBag"_ustr
) >>= aGrabBag
;
1508 std::vector
<OUString
> aClrMap
;
1509 aClrMap
.reserve(12);
1510 uno::Sequence
<beans::PropertyValue
> aClrMapPropValue
;
1511 if(aGrabBag
.hasElements())
1513 for (const auto& rProp
: aGrabBag
)
1515 if (rProp
.Name
== "OOXColorMap")
1517 rProp
.Value
>>= aClrMapPropValue
;
1523 if (aClrMapPropValue
.getLength())
1526 sal_Int32 nToken
= XML_TOKEN_INVALID
;
1527 for(const auto& item
: aClrMapPropValue
)
1529 item
.Value
>>= nToken
;
1532 case XML_dk1
: sName
= u
"dk1"_ustr
; break;
1533 case XML_lt1
: sName
= u
"lt1"_ustr
; break;
1534 case XML_dk2
: sName
= u
"dk2"_ustr
; break;
1535 case XML_lt2
: sName
= u
"lt2"_ustr
; break;
1536 case XML_accent1
: sName
= u
"accent1"_ustr
; break;
1537 case XML_accent2
: sName
= u
"accent2"_ustr
; break;
1538 case XML_accent3
: sName
= u
"accent3"_ustr
; break;
1539 case XML_accent4
: sName
= u
"accent4"_ustr
; break;
1540 case XML_accent5
: sName
= u
"accent5"_ustr
; break;
1541 case XML_accent6
: sName
= u
"accent6"_ustr
; break;
1542 case XML_hlink
: sName
= u
"hlink"_ustr
; break;
1543 case XML_folHlink
: sName
= u
"folHlink"_ustr
; break;
1545 aClrMap
.push_back(sName
);
1547 assert(aClrMap
.size() == 12 && "missing entries for ClrMap");
1551 // default clrMap to export ".odp" files to ".pptx"
1552 aClrMap
= { u
"lt1"_ustr
, u
"dk1"_ustr
, u
"lt2"_ustr
, u
"dk2"_ustr
,
1553 u
"accent1"_ustr
, u
"accent2"_ustr
, u
"accent3"_ustr
, u
"accent4"_ustr
,
1554 u
"accent5"_ustr
, u
"accent6"_ustr
, u
"hlink"_ustr
, u
"folHlink"_ustr
};
1557 pFS
->singleElementNS(XML_p
, XML_clrMap
,
1558 XML_bg1
, aClrMap
[0],
1559 XML_tx1
, aClrMap
[1],
1560 XML_bg2
, aClrMap
[2],
1561 XML_tx2
, aClrMap
[3],
1562 XML_accent1
, aClrMap
[4],
1563 XML_accent2
, aClrMap
[5],
1564 XML_accent3
, aClrMap
[6],
1565 XML_accent4
, aClrMap
[7],
1566 XML_accent5
, aClrMap
[8],
1567 XML_accent6
, aClrMap
[9],
1568 XML_hlink
, aClrMap
[10],
1569 XML_folHlink
, aClrMap
[11]);
1572 // use master's id type as they have same range, mso does that as well
1573 pFS
->startElementNS(XML_p
, XML_sldLayoutIdLst
);
1575 auto getLayoutsUsedForMaster
= [](SdrPage
* pMaster
) -> std::unordered_set
<sal_Int32
>
1580 std::unordered_set
<sal_Int32
> aUsedLayouts
{};
1581 for (const auto* pPageUser
: pMaster
->GetPageUsers())
1583 const auto* pMasterPageDescriptor
1584 = dynamic_cast<const sdr::MasterPageDescriptor
*>(pPageUser
);
1586 if (!pMasterPageDescriptor
)
1590 = static_cast<SdPage
&>(pMasterPageDescriptor
->GetOwnerPage()).GetAutoLayout();
1591 aUsedLayouts
.insert(eLayout
);
1593 return aUsedLayouts
;
1596 std::unordered_set
<sal_Int32
> aLayouts
= getLayoutsUsedForMaster(pMasterPage
);
1598 css::uno::Reference
< css::beans::XPropertySet
> xPagePropSet
;
1599 xPagePropSet
.set(mXDrawPage
, UNO_QUERY
);
1600 if (xPagePropSet
.is())
1603 if (GetPropertyValue(aAny
, xPagePropSet
, u
"SlideLayout"_ustr
))
1604 aLayouts
.insert(aAny
.get
<sal_Int32
>());
1607 OUString aSlideName
;
1608 Reference
< XNamed
> xNamed(mXDrawPage
, UNO_QUERY
);
1610 aSlideName
= xNamed
->getName();
1612 for (auto nLayout
: aLayouts
)
1614 ImplWritePPTXLayout(nLayout
, nPageNum
, aSlideName
);
1615 AddLayoutIdAndRelation(pFS
, GetLayoutFileId(nLayout
, nPageNum
));
1618 pFS
->endElementNS(XML_p
, XML_sldLayoutIdLst
);
1620 pFS
->endElementNS(XML_p
, XML_sldMaster
);
1622 SAL_INFO("sd.eppt", "----------------");
1627 sal_Int32
PowerPointExport::GetLayoutFileId(sal_Int32 nOffset
, sal_uInt32 nMasterNum
)
1629 SAL_INFO("sd.eppt", "GetLayoutFileId offset: " << nOffset
<< " master: " << nMasterNum
);
1630 if (mLayoutInfo
[ nOffset
].mnFileIdArray
.size() <= nMasterNum
)
1633 return mLayoutInfo
[ nOffset
].mnFileIdArray
[ nMasterNum
];
1636 void PowerPointExport::ImplWritePPTXLayout(sal_Int32 nOffset
, sal_uInt32 nMasterNum
, const OUString
& aSlideName
)
1638 SAL_INFO("sd.eppt", "write layout: " << nOffset
);
1640 Reference
< drawing::XDrawPagesSupplier
> xDPS(getModel(), uno::UNO_QUERY
);
1641 Reference
< drawing::XDrawPages
> xDrawPages
= xDPS
->getDrawPages();
1642 Reference
< drawing::XDrawPage
> xSlide
= xDrawPages
->insertNewByIndex(xDrawPages
->getCount());
1644 #if OSL_DEBUG_LEVEL >= 2
1646 printf("new page created\n");
1649 Reference
< beans::XPropertySet
> xPropSet(xSlide
, uno::UNO_QUERY
);
1650 xPropSet
->setPropertyValue(u
"Layout"_ustr
, Any(short(aLayoutInfo
[ nOffset
].nType
)));
1651 #if OSL_DEBUG_LEVEL > 1
1652 dump_pset(xPropSet
);
1654 mXPagePropSet
.set(xSlide
, UNO_QUERY
);
1657 if (mLayoutInfo
[ nOffset
].mnFileIdArray
.size() < mnMasterPages
)
1659 mLayoutInfo
[ nOffset
].mnFileIdArray
.resize(mnMasterPages
);
1662 if (mLayoutInfo
[ nOffset
].mnFileIdArray
[ nMasterNum
] != 0)
1666 = openFragmentStreamWithSerializer("ppt/slideLayouts/slideLayout" +
1667 OUString::number(mnLayoutFileIdMax
) + ".xml",
1668 u
"application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml"_ustr
);
1670 // add implicit relation of slide layout to slide master
1671 addRelation(pFS
->getOutputStream(),
1672 oox::getRelationship(Relationship::SLIDEMASTER
),
1673 Concat2View("../slideMasters/slideMaster" + OUString::number(nMasterNum
+ 1) + ".xml"));
1675 pFS
->startElementNS(XML_p
, XML_sldLayout
,
1677 XML_type
, aLayoutInfo
[ nOffset
].sType
,
1680 if (!aSlideName
.isEmpty())
1682 pFS
->startElementNS(XML_p
, XML_cSld
,
1683 XML_name
, aSlideName
);
1687 pFS
->startElementNS(XML_p
, XML_cSld
,
1688 XML_name
, aLayoutInfo
[nOffset
].sName
);
1690 //pFS->write( MINIMAL_SPTREE ); // TODO: write actual shape tree
1691 WriteShapeTree(pFS
, LAYOUT
, true);
1693 pFS
->endElementNS(XML_p
, XML_cSld
);
1695 pFS
->endElementNS(XML_p
, XML_sldLayout
);
1697 mLayoutInfo
[ nOffset
].mnFileIdArray
[ nMasterNum
] = mnLayoutFileIdMax
;
1699 mnLayoutFileIdMax
++;
1701 xDrawPages
->remove(xSlide
);
1706 void PowerPointExport::WriteShapeTree(const FSHelperPtr
& pFS
, PageType ePageType
, bool bMaster
)
1708 PowerPointShapeExport
aDML(pFS
, &maShapeMap
, this);
1709 aDML
.SetMaster(bMaster
);
1710 aDML
.SetPageType(ePageType
);
1711 aDML
.SetBackgroundDark(mbIsBackgroundDark
);
1713 pFS
->startElementNS(XML_p
, XML_spTree
);
1714 pFS
->write(MAIN_GROUP
);
1716 ResetGroupTable(mXShapes
->getCount());
1718 while (GetNextGroupEntry())
1721 sal_uInt32 nGroups
= GetGroupsClosed();
1722 for (sal_uInt32 i
= 0; i
< nGroups
; i
++)
1724 SAL_INFO("sd.eppt", "leave group");
1727 if (GetShapeByIndex(GetCurrentGroupIndex(), true))
1729 SAL_INFO("sd.eppt", "mType: " << mType
);
1730 const SdrObjGroup
* pDiagramCandidate(dynamic_cast<const SdrObjGroup
*>(SdrObject::getSdrObjectFromXShape(mXShape
)));
1731 const bool bIsDiagram(nullptr != pDiagramCandidate
&& pDiagramCandidate
->isDiagram());
1734 WriteDiagram(pFS
, aDML
, mXShape
, mnDiagramId
++);
1736 aDML
.WriteShape(mXShape
);
1740 if ( ePageType
== NORMAL
|| ePageType
== LAYOUT
)
1741 WritePlaceholderReferenceShapes(aDML
, ePageType
);
1742 pFS
->endElementNS(XML_p
, XML_spTree
);
1745 ShapeExport
& PowerPointShapeExport::WritePageShape(const Reference
< XShape
>& xShape
, PageType ePageType
, bool bPresObj
)
1747 if ((ePageType
== NOTICE
&& bPresObj
) || ePageType
== LAYOUT
|| ePageType
== MASTER
)
1748 return WritePlaceholderShape(xShape
, SlideImage
);
1750 return WriteTextShape(xShape
);
1753 bool PowerPointShapeExport::WritePlaceholder(const Reference
< XShape
>& xShape
, PlaceholderType ePlaceholder
, bool bMaster
)
1755 SAL_INFO("sd.eppt", "WritePlaceholder " << bMaster
<< " " << ShapeExport::NonEmptyText(xShape
));
1760 Reference
<XPropertySet
> xShapeProps(xShape
, UNO_QUERY
);
1761 if (xShapeProps
->getPropertyValue(u
"IsPresentationObject"_ustr
).get
<bool>())
1763 WritePlaceholderShape(xShape
, ePlaceholder
);
1775 ShapeExport
& PowerPointShapeExport::WritePlaceholderShape(const Reference
< XShape
>& xShape
, PlaceholderType ePlaceholder
)
1777 Reference
<XPropertySet
> xProps(xShape
, UNO_QUERY
);
1778 bool bUseBackground(false);
1779 if (xProps
.is() && xProps
->getPropertySetInfo()->hasPropertyByName(u
"FillUseSlideBackground"_ustr
))
1780 xProps
->getPropertyValue(u
"FillUseSlideBackground"_ustr
) >>= bUseBackground
;
1783 mpFS
->startElementNS(XML_p
, XML_sp
, XML_useBgFill
, "1");
1785 mpFS
->startElementNS(XML_p
, XML_sp
);
1787 // non visual shape properties
1788 mpFS
->startElementNS(XML_p
, XML_nvSpPr
);
1789 const OString
aPlaceholderID("PlaceHolder " + OString::number(mnShapeIdMax
++));
1790 WriteNonVisualDrawingProperties(xShape
, aPlaceholderID
.getStr());
1791 mpFS
->startElementNS(XML_p
, XML_cNvSpPr
);
1792 mpFS
->singleElementNS(XML_a
, XML_spLocks
, XML_noGrp
, "1");
1793 mpFS
->endElementNS(XML_p
, XML_cNvSpPr
);
1794 mpFS
->startElementNS(XML_p
, XML_nvPr
);
1796 bool bUsePlaceholderIndex
1797 = ePlaceholder
== Footer
|| ePlaceholder
== DateAndTime
|| ePlaceholder
== SlideNumber
;
1798 const char* pType
= getPlaceholderTypeName(ePlaceholder
);
1800 SAL_INFO("sd.eppt", "write placeholder " << pType
);
1801 if (bUsePlaceholderIndex
)
1803 mpFS
->singleElementNS(
1804 XML_p
, XML_ph
, XML_type
, pType
, XML_idx
,
1806 static_cast<PowerPointExport
*>(GetFB())->CreateNewPlaceholderIndex(xShape
)));
1810 if ((mePageType
== PageType::LAYOUT
|| mePageType
== PageType::NORMAL
)
1811 && ePlaceholder
== Outliner
)
1812 mpFS
->singleElementNS(XML_p
, XML_ph
);
1814 mpFS
->singleElementNS(XML_p
, XML_ph
, XML_type
, pType
);
1816 mpFS
->endElementNS(XML_p
, XML_nvPr
);
1817 mpFS
->endElementNS(XML_p
, XML_nvSpPr
);
1819 // visual shape properties
1820 mpFS
->startElementNS(XML_p
, XML_spPr
);
1821 WriteShapeTransformation(xShape
, XML_a
);
1822 WritePresetShape("rect"_ostr
);
1825 WriteBlipFill(xProps
, u
"Graphic"_ustr
);
1826 // Do not forget to export the visible properties.
1827 WriteFill( xProps
, xShape
->getSize());
1828 WriteOutline( xProps
);
1829 WriteShapeEffects( xProps
);
1831 bool bHas3DEffectinShape
= false;
1832 uno::Sequence
<beans::PropertyValue
> grabBag
;
1833 if (xProps
->getPropertySetInfo()->hasPropertyByName(u
"InteropGrabBag"_ustr
))
1834 xProps
->getPropertyValue(u
"InteropGrabBag"_ustr
) >>= grabBag
;
1836 for (auto const& it
: grabBag
)
1837 if (it
.Name
== "3DEffectProperties")
1838 bHas3DEffectinShape
= true;
1840 if( bHas3DEffectinShape
)
1841 Write3DEffects( xProps
, /*bIsText=*/false );
1843 mpFS
->endElementNS(XML_p
, XML_spPr
);
1845 WriteTextBox(xShape
, XML_p
, /*bWritePropertiesAsLstStyles=*/bUsePlaceholderIndex
);
1847 mpFS
->endElementNS(XML_p
, XML_sp
);
1852 ShapeExport
& PowerPointShapeExport::WritePlaceholderReferenceShape(
1853 PlaceholderType ePlaceholder
, sal_Int32 nReferencedPlaceholderIdx
, PageType ePageType
,
1854 const Reference
<XPropertySet
>& rXPagePropSet
)
1856 mpFS
->startElementNS(XML_p
, XML_sp
);
1858 // non visual shape properties
1859 mpFS
->startElementNS(XML_p
, XML_nvSpPr
);
1860 const OString
aPlaceholderID("PlaceHolder " + OString::number(mnShapeIdMax
++));
1861 GetFS()->singleElementNS(XML_p
, XML_cNvPr
, XML_id
, OString::number(mnShapeIdMax
), XML_name
,
1864 mpFS
->startElementNS(XML_p
, XML_cNvSpPr
);
1865 mpFS
->singleElementNS(XML_a
, XML_spLocks
, XML_noGrp
, "1");
1866 mpFS
->endElementNS(XML_p
, XML_cNvSpPr
);
1867 mpFS
->startElementNS(XML_p
, XML_nvPr
);
1869 const char* pType
= getPlaceholderTypeName(ePlaceholder
);
1870 mpFS
->singleElementNS(XML_p
, XML_ph
, XML_type
, pType
, XML_idx
,
1871 OString::number(nReferencedPlaceholderIdx
));
1872 mpFS
->endElementNS(XML_p
, XML_nvPr
);
1873 mpFS
->endElementNS(XML_p
, XML_nvSpPr
);
1875 // visual shape properties
1876 mpFS
->startElementNS(XML_p
, XML_spPr
);
1877 mpFS
->endElementNS(XML_p
, XML_spPr
);
1879 WritePlaceholderReferenceTextBody(ePlaceholder
, ePageType
, rXPagePropSet
);
1881 mpFS
->endElementNS(XML_p
, XML_sp
);
1886 ShapeExport
& PowerPointShapeExport::WritePlaceholderReferenceTextBody(
1887 PlaceholderType ePlaceholder
, PageType ePageType
, const Reference
<XPropertySet
>& xPagePropSet
)
1889 mpFS
->startElementNS(XML_p
, XML_txBody
);
1890 mpFS
->singleElementNS(XML_a
, XML_bodyPr
);
1891 mpFS
->startElementNS(XML_a
, XML_p
);
1893 switch (ePlaceholder
)
1899 OUString aFooterText
;
1900 if (ePageType
== LAYOUT
)
1902 aFooterText
= "Footer";
1906 xPagePropSet
->getPropertyValue(u
"FooterText"_ustr
) >>= aFooterText
;
1908 mpFS
->startElementNS(XML_a
, XML_r
);
1909 mpFS
->startElementNS(XML_a
, XML_t
);
1910 mpFS
->writeEscaped(aFooterText
);
1911 mpFS
->endElementNS(XML_a
, XML_t
);
1912 mpFS
->endElementNS(XML_a
, XML_r
);
1918 sal_Int32 nSlideNum
= 0;
1919 if (ePageType
== LAYOUT
)
1925 xPagePropSet
->getPropertyValue(u
"Number"_ustr
) >>= nSlideNum
;
1926 aSlideNum
= OUString::number(nSlideNum
);
1928 OString
aUUID(comphelper::xml::generateGUIDString());
1929 mpFS
->startElementNS(XML_a
, XML_fld
, XML_id
, aUUID
, XML_type
, "slidenum");
1930 mpFS
->startElementNS(XML_a
, XML_t
);
1931 mpFS
->writeEscaped(aSlideNum
);
1932 mpFS
->endElementNS(XML_a
, XML_t
);
1933 mpFS
->endElementNS(XML_a
, XML_fld
);
1938 OUString aDateTimeType
= u
"datetime1"_ustr
;
1939 bool bIsDateTimeFixed
= false;
1940 xPagePropSet
->getPropertyValue(u
"IsDateTimeFixed"_ustr
) >>= bIsDateTimeFixed
;
1942 OUString aDateTimeText
= u
"Date"_ustr
;
1943 const LanguageTag
& rLanguageTag
= Application::GetSettings().GetLanguageTag();
1945 if(ePageType
!= LAYOUT
&& !bIsDateTimeFixed
)
1947 sal_Int32 nDateTimeFormat
= 0;
1948 xPagePropSet
->getPropertyValue(u
"DateTimeFormat"_ustr
) >>= nDateTimeFormat
;
1950 // 4 LSBs represent the date
1951 SvxDateFormat eDate
= static_cast<SvxDateFormat
>(nDateTimeFormat
& 0x0f);
1952 // the 4 bits after the date bits represent the time
1953 SvxTimeFormat eTime
= static_cast<SvxTimeFormat
>(nDateTimeFormat
>> 4);
1954 aDateTimeType
= GetDatetimeTypeFromDateTime(eDate
, eTime
);
1956 if (aDateTimeType
== "datetime")
1957 aDateTimeType
= "datetime1";
1959 ::DateTime
aDateTime( ::DateTime::SYSTEM
);
1961 aDateTimeText
= SvxDateTimeField::GetFormatted(
1962 aDateTime
, aDateTime
, eDate
,
1963 eTime
, *(SdModule::get()->GetNumberFormatter()),
1964 rLanguageTag
.getLanguageType());
1967 if(!bIsDateTimeFixed
)
1969 OString
aUUID(comphelper::xml::generateGUIDString());
1970 mpFS
->startElementNS(XML_a
, XML_fld
, XML_id
, aUUID
, XML_type
, aDateTimeType
);
1974 xPagePropSet
->getPropertyValue(u
"DateTimeText"_ustr
) >>= aDateTimeText
;
1975 mpFS
->startElementNS(XML_a
, XML_r
);
1978 mpFS
->startElementNS(XML_a
, XML_rPr
, XML_lang
, rLanguageTag
.getBcp47MS());
1979 mpFS
->endElementNS(XML_a
, XML_rPr
);
1981 mpFS
->startElementNS(XML_a
, XML_t
);
1982 mpFS
->writeEscaped(aDateTimeText
);
1983 mpFS
->endElementNS(XML_a
, XML_t
);
1985 mpFS
->endElementNS(XML_a
, bIsDateTimeFixed
? XML_r
: XML_fld
);
1989 SAL_INFO("sd.eppt", "warning: no defined textbody for referenced placeholder type: "
1992 mpFS
->endElementNS(XML_a
, XML_p
);
1993 mpFS
->endElementNS(XML_p
, XML_txBody
);
1998 void PowerPointExport::WriteDefaultColorSchemes(const FSHelperPtr
& pFS
)
2000 for (int nId
= PredefinedClrSchemeId::dk2
; nId
!= PredefinedClrSchemeId::Count
; nId
++)
2002 OUString
sName(getPredefinedClrNames(static_cast<PredefinedClrSchemeId
>(nId
)));
2003 sal_Int32 nColor
= 0;
2007 case PredefinedClrSchemeId::dk2
:
2010 case PredefinedClrSchemeId::lt2
:
2013 case PredefinedClrSchemeId::accent1
:
2016 case PredefinedClrSchemeId::accent2
:
2019 case PredefinedClrSchemeId::accent3
:
2022 case PredefinedClrSchemeId::accent4
:
2025 case PredefinedClrSchemeId::accent5
:
2028 case PredefinedClrSchemeId::accent6
:
2031 case PredefinedClrSchemeId::hlink
:
2034 case PredefinedClrSchemeId::folHlink
:
2039 OUString sOpenColorScheme
= "<a:" + sName
+ ">";
2040 pFS
->write(sOpenColorScheme
);
2042 pFS
->singleElementNS(XML_a
, XML_srgbClr
, XML_val
, I32SHEX(nColor
));
2044 OUString sCloseColorScheme
= "</a:" + sName
+ ">";
2045 pFS
->write(sCloseColorScheme
);
2049 void PowerPointExport::WriteTheme(sal_Int32 nThemeNum
, model::Theme
* pTheme
)
2053 OUString sThemePath
= "ppt/theme/theme" + OUString::number(nThemeNum
+ 1) + ".xml";
2055 oox::ThemeExport
aThemeExport(this, DOCUMENT_PPTX
);
2057 aThemeExport
.write(sThemePath
, *pTheme
);
2060 bool PowerPointExport::ImplCreateDocument()
2062 mbCreateNotes
= false;
2064 for (sal_uInt32 i
= 0; i
< mnPages
; i
++)
2066 if (!GetPageByIndex(i
, NOTICE
))
2069 if (ContainsOtherShapeThanPlaceholders())
2071 mbCreateNotes
= true;
2079 void PowerPointExport::WriteNotesMaster()
2081 SAL_INFO("sd.eppt", "write Notes master\n---------------");
2083 mPresentationFS
->startElementNS(XML_p
, XML_notesMasterIdLst
);
2085 OUString sRelId
= addRelation(mPresentationFS
->getOutputStream(),
2086 oox::getRelationship(Relationship::NOTESMASTER
),
2087 u
"notesMasters/notesMaster1.xml");
2089 mPresentationFS
->singleElementNS(XML_p
, XML_notesMasterId
,
2090 FSNS(XML_r
, XML_id
), sRelId
);
2092 mPresentationFS
->endElementNS(XML_p
, XML_notesMasterIdLst
);
2095 openFragmentStreamWithSerializer(u
"ppt/notesMasters/notesMaster1.xml"_ustr
,
2096 u
"application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml"_ustr
);
2097 // write theme per master
2099 // TODO: Need to implement theme support for note master, so the
2100 // note master has his own theme associated.
2102 // For now just use the default theme
2103 auto const* pDefaultColorSet
= svx::ColorSets::get().getColorSet(u
"LibreOffice");
2104 if (pDefaultColorSet
)
2106 auto pTheme
= std::make_shared
<model::Theme
>("Office Theme");
2107 pTheme
->setColorSet(std::make_shared
<model::ColorSet
>(*pDefaultColorSet
));
2109 WriteTheme(mnMasterPages
, pTheme
.get());
2111 // add implicit relation to the presentation theme
2112 addRelation(pFS
->getOutputStream(),
2113 oox::getRelationship(Relationship::THEME
),
2114 Concat2View("../theme/theme" + OUString::number(mnMasterPages
+ 1) + ".xml"));
2117 pFS
->startElementNS(XML_p
, XML_notesMaster
, PNMSS
);
2119 pFS
->startElementNS(XML_p
, XML_cSld
);
2121 Reference
< XPropertySet
> aXBackgroundPropSet
;
2122 if (ImplGetPropertyValue(mXPagePropSet
, u
"Background"_ustr
) &&
2123 (mAny
>>= aXBackgroundPropSet
))
2124 ImplWriteBackground(pFS
, aXBackgroundPropSet
);
2126 WriteShapeTree(pFS
, NOTICE
, true);
2128 pFS
->endElementNS(XML_p
, XML_cSld
);
2130 // color map - now it uses colors from hardcoded theme, once we eventually generate theme, this might need update
2131 pFS
->singleElementNS(XML_p
, XML_clrMap
,
2136 XML_accent1
, "accent1",
2137 XML_accent2
, "accent2",
2138 XML_accent3
, "accent3",
2139 XML_accent4
, "accent4",
2140 XML_accent5
, "accent5",
2141 XML_accent6
, "accent6",
2143 XML_folHlink
, "folHlink");
2145 pFS
->endElementNS(XML_p
, XML_notesMaster
);
2147 SAL_INFO("sd.eppt", "----------------");
2152 void PowerPointExport::embedEffectAudio(const FSHelperPtr
& pFS
, const OUString
& sUrl
, OUString
& sRelId
, OUString
& sName
)
2154 comphelper::LifecycleProxy aProxy
;
2156 if (!sUrl
.endsWithIgnoreAsciiCase(".wav"))
2159 uno::Reference
<io::XInputStream
> xAudioStream
;
2162 if (sUrl
.startsWith("vnd.sun.star.Package:"))
2164 uno::Reference
<document::XStorageBasedDocument
> xStorageBasedDocument(getModel(), uno::UNO_QUERY
);
2165 if (!xStorageBasedDocument
.is())
2168 uno::Reference
<embed::XStorage
> xDocumentStorage
= xStorageBasedDocument
->getDocumentStorage();
2169 if (!xDocumentStorage
.is())
2172 uno::Reference
<io::XStream
> xStream
= comphelper::OStorageHelper::GetStreamAtPackageURL(xDocumentStorage
, sUrl
,
2173 css::embed::ElementModes::READ
, aProxy
);
2176 xAudioStream
= xStream
->getInputStream();
2179 xAudioStream
= comphelper::OStorageHelper::GetInputStreamFromURL(sUrl
, getComponentContext());
2181 catch (const Exception
&)
2183 TOOLS_WARN_EXCEPTION("sd", "PowerPointExport::embedEffectAudio");
2186 if (!xAudioStream
.is())
2189 int nLastSlash
= sUrl
.lastIndexOf('/');
2190 sName
= sUrl
.copy(nLastSlash
>= 0 ? nLastSlash
+ 1 : 0);
2192 OUString sPath
= "../media/" + sName
;
2193 sRelId
= addRelation(pFS
->getOutputStream(),
2194 oox::getRelationship(Relationship::AUDIO
), sPath
);
2196 uno::Reference
<io::XOutputStream
> xOutputStream
= openFragmentStream(sPath
.replaceAt(0, 2, u
"/ppt"),
2197 u
"audio/x-wav"_ustr
);
2199 comphelper::OStorageHelper::CopyInputToOutput(xAudioStream
, xOutputStream
);
2202 sal_Int32
PowerPointExport::GetShapeID(const Reference
<XShape
>& rXShape
)
2204 return ShapeExport::GetShapeID(rXShape
, &maShapeMap
);
2207 sal_Int32
PowerPointExport::GetNextAnimationNodeID()
2209 return mnAnimationNodeIdMax
++;
2212 bool PowerPointExport::ImplCreateMainNotes()
2220 OUString
PowerPointExport::getImplementationName()
2222 return u
"com.sun.star.comp.Impress.oox.PowerPointExport"_ustr
;
2225 void PowerPointExport::WriteDiagram(const FSHelperPtr
& pFS
, PowerPointShapeExport
& rDML
, const css::uno::Reference
<css::drawing::XShape
>& rXShape
, int nDiagramId
)
2227 SAL_INFO("sd.eppt", "writing Diagram " + OUString::number(nDiagramId
));
2228 pFS
->startElementNS(XML_p
, XML_graphicFrame
);
2229 rDML
.WriteDiagram(rXShape
, nDiagramId
);
2230 pFS
->endElementNS(XML_p
, XML_graphicFrame
);
2233 void PowerPointExport::WritePlaceholderReferenceShapes(PowerPointShapeExport
& rDML
, PageType ePageType
)
2235 bool bCheckProps
= ePageType
== NORMAL
;
2236 Reference
<XShape
> xShape
;
2239 if (ePageType
== LAYOUT
2240 || (bCheckProps
&& PropValue::GetPropertyValue(aAny
, mXPagePropSet
, u
"IsFooterVisible"_ustr
, true)
2241 && aAny
== true && GetPropertyValue(aAny
, mXPagePropSet
, u
"FooterText"_ustr
, true)
2242 && (aAny
>>= aText
) && !aText
.isEmpty()))
2244 if ((xShape
= GetReferencedPlaceholderXShape(Footer
, ePageType
)))
2246 const auto iter
= maPlaceholderShapeToIndexMap
.find(xShape
);
2247 assert(iter
!= maPlaceholderShapeToIndexMap
.end());
2248 rDML
.WritePlaceholderReferenceShape(Footer
,
2250 ePageType
, mXPagePropSet
);
2254 if (ePageType
== LAYOUT
2256 && PropValue::GetPropertyValue(aAny
, mXPagePropSet
, u
"IsPageNumberVisible"_ustr
, true)
2259 if ((xShape
= GetReferencedPlaceholderXShape(SlideNumber
, ePageType
)))
2261 const auto iter
= maPlaceholderShapeToIndexMap
.find(xShape
);
2262 assert(iter
!= maPlaceholderShapeToIndexMap
.end());
2263 rDML
.WritePlaceholderReferenceShape(SlideNumber
,
2265 ePageType
, mXPagePropSet
);
2269 if (ePageType
== LAYOUT
2271 && PropValue::GetPropertyValue(aAny
, mXPagePropSet
, u
"IsDateTimeVisible"_ustr
, true)
2273 && ((GetPropertyValue(aAny
, mXPagePropSet
, u
"DateTimeText"_ustr
, true) && (aAny
>>= aText
)
2274 && !aText
.isEmpty())
2275 || mXPagePropSet
->getPropertyValue(u
"IsDateTimeFixed"_ustr
) == false)))
2277 if ((xShape
= GetReferencedPlaceholderXShape(DateAndTime
, ePageType
)))
2279 const auto iter
= maPlaceholderShapeToIndexMap
.find(xShape
);
2280 assert(iter
!= maPlaceholderShapeToIndexMap
.end());
2281 rDML
.WritePlaceholderReferenceShape(DateAndTime
,
2283 ePageType
, mXPagePropSet
);
2288 sal_Int32
PowerPointExport::CreateNewPlaceholderIndex(const css::uno::Reference
<XShape
> &rXShape
)
2290 maPlaceholderShapeToIndexMap
.insert({rXShape
, mnPlaceholderIndexMax
});
2291 return mnPlaceholderIndexMax
++;
2294 Reference
<XShape
> PowerPointExport::GetReferencedPlaceholderXShape(const PlaceholderType eType
,
2295 PageType ePageType
) const
2297 PresObjKind ePresObjKind
= PresObjKind::NONE
;
2300 case oox::core::None
:
2302 case oox::core::SlideImage
:
2304 case oox::core::Notes
:
2306 case oox::core::Header
:
2307 ePresObjKind
= PresObjKind::Header
;
2309 case oox::core::Footer
:
2310 ePresObjKind
= PresObjKind::Footer
;
2312 case oox::core::SlideNumber
:
2313 ePresObjKind
= PresObjKind::SlideNumber
;
2315 case oox::core::DateAndTime
:
2316 ePresObjKind
= PresObjKind::DateTime
;
2318 case oox::core::Outliner
:
2320 case oox::core::Title
:
2321 ePresObjKind
= PresObjKind::Title
;
2323 case oox::core::Subtitle
:
2326 if (ePresObjKind
!= PresObjKind::NONE
)
2328 SdPage
* pMasterPage
;
2329 if (ePageType
== LAYOUT
)
2331 // since Layout pages do not have drawpages themselves - mXDrawPage is still the master they reference to..
2332 pMasterPage
= SdPage::getImplementation(mXDrawPage
);
2336 pMasterPage
= &static_cast<SdPage
&>(SdPage::getImplementation(mXDrawPage
)->TRG_GetMasterPage());
2338 if (SdrObject
* pMasterFooter
= pMasterPage
->GetPresObj(ePresObjKind
))
2339 return GetXShapeForSdrObject(pMasterFooter
);
2345 extern "C" SAL_DLLPUBLIC_EXPORT
uno::XInterface
*
2346 css_comp_Impress_oox_PowerPointExport(uno::XComponentContext
* rxCtxt
,
2347 uno::Sequence
<css::uno::Any
> const& rArguments
)
2349 return cppu::acquire(new PowerPointExport(rxCtxt
, rArguments
));
2352 #if OSL_DEBUG_LEVEL > 1
2353 void dump_pset(Reference
< XPropertySet
> const& rXPropSet
)
2355 Reference
< XPropertySetInfo
> info
= rXPropSet
->getPropertySetInfo();
2356 Sequence
< beans::Property
> props
= info
->getProperties();
2358 for (int i
=0; i
< props
.getLength(); i
++)
2360 OString name
= OUStringToOString(props
[i
].Name
, RTL_TEXTENCODING_UTF8
);
2362 Any value
= rXPropSet
->getPropertyValue(props
[i
].Name
);
2367 RectanglePoint pointValue
;
2369 if (value
>>= strValue
)
2370 SAL_INFO("sd.eppt", name
<< " = \"" << strValue
<< "\"");
2371 else if (value
>>= intValue
)
2372 SAL_INFO("sd.eppt", name
<< " = " << intValue
<< "(hex : " << std::hex
<< intValue
<< ")");
2373 else if (value
>>= boolValue
)
2374 SAL_INFO("sd.eppt", name
<< " = " << boolValue
<< " (bool)");
2375 else if (value
>>= pointValue
)
2376 SAL_INFO("sd.eppt", name
<< " = " << static_cast<int>(pointValue
) << " (RectanglePoint)");
2378 SAL_INFO("sd.eppt", "??? <unhandled type>");
2383 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */