sd: support for saving into .potx file
[LibreOffice.git] / sd / source / filter / eppt / pptx-epptooxml.cxx
blobd2a5231c7d2e7424386207c13cf67d34fb259c3e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdio.h>
21 #include <o3tl/any.hxx>
22 #include <oox/drawingml/chart/chartconverter.hxx>
23 #include <oox/drawingml/clrscheme.hxx>
24 #include <oox/token/namespaces.hxx>
25 #include <oox/token/tokens.hxx>
26 #include <oox/token/relationship.hxx>
27 #include <oox/ole/vbaproject.hxx>
28 #include "epptooxml.hxx"
29 #include "epptdef.hxx"
30 #include <oox/export/shapes.hxx>
32 #include <comphelper/sequenceashashmap.hxx>
33 #include <comphelper/storagehelper.hxx>
34 #include <cppuhelper/implementationentry.hxx>
35 #include <cppuhelper/factory.hxx>
36 #include <sax/fshelper.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <sal/log.hxx>
39 #include <filter/msfilter/escherex.hxx>
40 #include <tools/poly.hxx>
41 #include <com/sun/star/animations/TransitionType.hpp>
42 #include <com/sun/star/animations/TransitionSubType.hpp>
43 #include <com/sun/star/beans/Property.hpp>
44 #include <com/sun/star/beans/XPropertySetInfo.hpp>
45 #include <com/sun/star/container/XEnumerationAccess.hpp>
46 #include <com/sun/star/drawing/FillStyle.hpp>
47 #include <com/sun/star/drawing/RectanglePoint.hpp>
48 #include <com/sun/star/drawing/XDrawPages.hpp>
49 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
50 #include <com/sun/star/embed/ElementModes.hpp>
51 #include <com/sun/star/geometry/RealPoint2D.hpp>
52 #include <com/sun/star/office/XAnnotationEnumeration.hpp>
53 #include <com/sun/star/office/XAnnotationAccess.hpp>
54 #include <com/sun/star/presentation/AnimationSpeed.hpp>
55 #include <com/sun/star/util/DateTime.hpp>
56 #include <com/sun/star/task/XStatusIndicator.hpp>
57 #include <com/sun/star/frame/XModel.hpp>
58 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
60 #include <oox/export/utils.hxx>
61 #include <oox/ppt/pptfilterhelpers.hxx>
62 #include <basegfx/polygon/b2dpolypolygontools.hxx>
64 #include "pptexanimations.hxx"
65 #include "pptx-animations.hxx"
66 #include "../ppt/pptanimations.hxx"
68 #include <com/sun/star/document/XDocumentProperties.hpp>
69 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
70 #include <com/sun/star/document/XStorageBasedDocument.hpp>
71 #include <utility>
73 // presentation namespaces
74 #define PNMSS FSNS(XML_xmlns, XML_a), OUStringToOString(this->getNamespaceURL(OOX_NS(dml)), RTL_TEXTENCODING_UTF8).getStr(), \
75 FSNS(XML_xmlns, XML_p), OUStringToOString(this->getNamespaceURL(OOX_NS(ppt)), RTL_TEXTENCODING_UTF8).getStr(), \
76 FSNS(XML_xmlns, XML_r), OUStringToOString(this->getNamespaceURL(OOX_NS(officeRel)), RTL_TEXTENCODING_UTF8).getStr(), \
77 FSNS(XML_xmlns, XML_p14), OUStringToOString(this->getNamespaceURL(OOX_NS(p14)), RTL_TEXTENCODING_UTF8).getStr(), \
78 FSNS(XML_xmlns, XML_p15), OUStringToOString(this->getNamespaceURL(OOX_NS(p15)), RTL_TEXTENCODING_UTF8).getStr(), \
79 FSNS(XML_xmlns, XML_mc), OUStringToOString(this->getNamespaceURL(OOX_NS(mce)), RTL_TEXTENCODING_UTF8).getStr()
82 using namespace ::com::sun::star;
83 using namespace ::com::sun::star::animations;
84 using namespace ::com::sun::star::beans;
85 using namespace ::com::sun::star::container;
86 using namespace ::com::sun::star::drawing;
87 using namespace ::com::sun::star::geometry;
88 using namespace ::com::sun::star::presentation;
89 using namespace ::com::sun::star::office;
90 using namespace ::com::sun::star::text;
91 using namespace ::com::sun::star::uno;
92 using namespace ::com::sun::star::util;
93 using namespace ::ppt;
94 using ::com::sun::star::beans::XPropertySet;
95 using ::com::sun::star::beans::XPropertySetInfo;
96 using ::com::sun::star::container::XIndexAccess;
97 using ::sax_fastparser::FSHelperPtr;
98 using namespace oox::drawingml;
99 using namespace oox::core;
101 #if OSL_DEBUG_LEVEL > 1
102 void dump_pset(Reference< XPropertySet > const& rXPropSet);
103 #endif
105 namespace oox
107 namespace core
110 class PowerPointShapeExport : public ShapeExport
112 PowerPointExport& mrExport;
113 PageType mePageType;
114 bool mbMaster;
115 public:
116 PowerPointShapeExport(FSHelperPtr pFS, ShapeHashMap* pShapeMap, PowerPointExport* pFB);
117 void SetMaster(bool bMaster);
118 void SetPageType(PageType ePageType);
119 ShapeExport& WriteNonVisualProperties(const Reference< XShape >& xShape) override;
120 ShapeExport& WriteTextShape(const Reference< XShape >& xShape) override;
121 ShapeExport& WriteUnknownShape(const Reference< XShape >& xShape) override;
122 ShapeExport& WritePlaceholderShape(const Reference< XShape >& xShape, PlaceholderType ePlaceholder);
123 ShapeExport& WritePageShape(const Reference< XShape >& xShape, PageType ePageType, bool bPresObj);
125 // helper parts
126 bool WritePlaceholder(const Reference< XShape >& xShape, PlaceholderType ePlaceholder, bool bMaster);
132 enum PPTXLayout
134 LAYOUT_BLANK,
135 LAYOUT_TITLE_SLIDE,
136 LAYOUT_TITLE_CONTENT,
137 LAYOUT_TITLE_2CONTENT,
138 LAYOUT_TITLE,
139 LAYOUT_CENTERED_TEXT,
140 LAYOUT_TITLE_2CONTENT_CONTENT,
141 LAYOUT_TITLE_CONTENT_2CONTENT,
142 LAYOUT_TITLE_2CONTENT_OVER_CONTENT,
143 LAYOUT_TITLE_CONTENT_OVER_CONTENT,
144 LAYOUT_TITLE_4CONTENT,
145 LAYOUT_TITLE_6CONTENT,
146 LAYOUT_SIZE
149 struct PPTXLayoutInfo
151 int const nType;
152 const char* sName;
153 const char* sType;
156 static const PPTXLayoutInfo aLayoutInfo[LAYOUT_SIZE] =
158 { 20, "Blank Slide", "blank" },
159 { 0, "Title Slide", "tx" },
160 { 1, "Title, Content", "obj" },
161 { 3, "Title, 2 Content", "twoObj" },
162 { 19, "Title Only", "titleOnly" },
163 { 32, "Centered Text", "objOnly" }, // not exactly, but close
164 { 15, "Title, 2 Content and Content", "twoObjAndObj" },
165 { 12, "Title Content and 2 Content", "objAndTwoObj" },
166 { 16, "Title, 2 Content over Content", "twoObjOverTx" }, // not exactly, but close
167 { 14, "Title, Content over Content", "objOverTx" }, // not exactly, but close
168 { 18, "Title, 4 Content", "fourObj" },
169 { 34, "Title, 6 Content", "blank" } // not defined => blank
172 int PowerPointExport::GetPPTXLayoutId(int nOffset)
174 int nId = LAYOUT_BLANK;
176 SAL_INFO("sd.eppt", "GetPPTXLayoutId " << nOffset);
178 switch (nOffset)
180 case 0:
181 nId = LAYOUT_TITLE_SLIDE;
182 break;
183 case 1:
184 nId = LAYOUT_TITLE_CONTENT;
185 break;
186 case 3:
187 nId = LAYOUT_TITLE_2CONTENT;
188 break;
189 case 19:
190 nId = LAYOUT_TITLE;
191 break;
192 case 15:
193 nId = LAYOUT_TITLE_2CONTENT_CONTENT;
194 break;
195 case 12:
196 nId = LAYOUT_TITLE_CONTENT_2CONTENT;
197 break;
198 case 16:
199 nId = LAYOUT_TITLE_2CONTENT_OVER_CONTENT;
200 break;
201 case 14:
202 nId = LAYOUT_TITLE_CONTENT_OVER_CONTENT;
203 break;
204 case 18:
205 nId = LAYOUT_TITLE_4CONTENT;
206 break;
207 case 32:
208 nId = LAYOUT_CENTERED_TEXT;
209 break;
210 case 34:
211 nId = LAYOUT_TITLE_6CONTENT;
212 break;
213 case 20:
214 default:
215 nId = LAYOUT_BLANK;
216 break;
219 return nId;
222 PowerPointShapeExport::PowerPointShapeExport(FSHelperPtr pFS, ShapeHashMap* pShapeMap,
223 PowerPointExport* pFB)
224 : ShapeExport(XML_p, std::move(pFS), pShapeMap, pFB)
225 , mrExport(*pFB)
226 , mePageType(UNDEFINED)
227 , mbMaster(false)
231 void PowerPointShapeExport::SetMaster(bool bMaster)
233 mbMaster = bMaster;
236 void PowerPointShapeExport::SetPageType(PageType ePageType)
238 mePageType = ePageType;
241 ShapeExport& PowerPointShapeExport::WriteNonVisualProperties(const Reference< XShape >&)
243 GetFS()->singleElementNS(XML_p, XML_nvPr, FSEND);
245 return *this;
248 ShapeExport& PowerPointShapeExport::WriteTextShape(const Reference< XShape >& xShape)
250 OUString sShapeType = xShape->getShapeType();
252 SAL_INFO("sd.eppt", "shape(text) : " << USS(sShapeType));
254 if (sShapeType == "com.sun.star.drawing.TextShape" || sShapeType == "com.sun.star.drawing.GraphicObjectShape")
256 ShapeExport::WriteTextShape(xShape);
258 else if (sShapeType == "com.sun.star.presentation.DateTimeShape")
260 if (!WritePlaceholder(xShape, DateAndTime, mbMaster))
261 ShapeExport::WriteTextShape(xShape);
263 else if (sShapeType == "com.sun.star.presentation.FooterShape")
265 if (!WritePlaceholder(xShape, Footer, mbMaster))
266 ShapeExport::WriteTextShape(xShape);
268 else if (sShapeType == "com.sun.star.presentation.HeaderShape")
270 if (!WritePlaceholder(xShape, Header, mbMaster))
271 ShapeExport::WriteTextShape(xShape);
273 else if (sShapeType == "com.sun.star.presentation.NotesShape")
275 if (mePageType == NOTICE && mrExport.GetPresObj())
276 WritePlaceholderShape(xShape, Notes);
277 else
278 ShapeExport::WriteTextShape(xShape);
280 else if (sShapeType == "com.sun.star.presentation.OutlinerShape")
282 if (!WritePlaceholder(xShape, Outliner, mbMaster))
283 ShapeExport::WriteTextShape(xShape);
285 else if (sShapeType == "com.sun.star.presentation.SlideNumberShape")
287 if (!WritePlaceholder(xShape, SlideNumber, mbMaster))
288 ShapeExport::WriteTextShape(xShape);
290 else if (sShapeType == "com.sun.star.presentation.TitleTextShape")
292 if (!WritePlaceholder(xShape, Title, mbMaster))
293 ShapeExport::WriteTextShape(xShape);
295 else
296 SAL_WARN("sd.eppt", "PowerPointShapeExport::WriteTextShape: shape of type '" << sShapeType << "' is ignored");
298 return *this;
301 ShapeExport& PowerPointShapeExport::WriteUnknownShape(const Reference< XShape >& xShape)
303 OUString sShapeType = xShape->getShapeType();
305 SAL_INFO("sd.eppt", "shape(unknown): " << USS(sShapeType));
307 if (sShapeType == "com.sun.star.presentation.PageShape")
309 WritePageShape(xShape, mePageType, mrExport.GetPresObj());
311 else if (sShapeType == "com.sun.star.presentation.SubtitleShape")
313 if(mePageType != MASTER)
315 if (!WritePlaceholder(xShape, Subtitle, mbMaster))
316 ShapeExport::WriteTextShape(xShape);
319 else
320 SAL_WARN("sd.eppt", "unknown shape not handled: " << USS(sShapeType));
322 return *this;
325 PowerPointExport::PowerPointExport(const Reference< XComponentContext >& rContext, const uno::Sequence<uno::Any>& rArguments)
326 : XmlFilterBase(rContext)
327 , PPTWriterBase()
328 , mnLayoutFileIdMax(1)
329 , mnSlideIdMax(1 << 8)
330 , mnSlideMasterIdMax(1U << 31)
331 , mnAnimationNodeIdMax(1)
332 , mbCreateNotes(false)
334 comphelper::SequenceAsHashMap aArgumentsMap(rArguments);
335 mbPptm = aArgumentsMap.getUnpackedValueOrDefault("IsPPTM", false);
336 mbExportTemplate = aArgumentsMap.getUnpackedValueOrDefault("IsTemplate", false);
339 PowerPointExport::~PowerPointExport()
343 void PowerPointExport::writeDocumentProperties()
345 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(mXModel, uno::UNO_QUERY);
346 uno::Reference<document::XDocumentProperties> xDocProps = xDPS->getDocumentProperties();
348 if (xDocProps.is())
350 bool bSecurityOptOpenReadOnly = false;
351 uno::Reference< lang::XMultiServiceFactory > xFactory(mXModel, uno::UNO_QUERY);
352 uno::Reference< beans::XPropertySet > xSettings(xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY);
355 xSettings->getPropertyValue("LoadReadonly") >>= bSecurityOptOpenReadOnly;
357 catch( Exception& )
360 exportDocumentProperties(xDocProps, bSecurityOptOpenReadOnly);
363 exportCustomFragments();
366 bool PowerPointExport::importDocument() throw()
368 return false;
371 bool PowerPointExport::exportDocument()
373 DrawingML::ResetCounters();
374 maShapeMap.clear();
376 mXModel.set(getModel(), UNO_QUERY);
378 //write document properties
379 writeDocumentProperties();
381 addRelation(oox::getRelationship(Relationship::OFFICEDOCUMENT), "ppt/presentation.xml");
383 OUString aMediaType;
384 if (mbPptm)
386 if (mbExportTemplate)
388 aMediaType = "application/vnd.ms-powerpoint.template.macroEnabled.main+xml";
390 else
392 aMediaType = "application/vnd.ms-powerpoint.presentation.macroEnabled.main+xml";
395 else
397 if (mbExportTemplate)
399 aMediaType = "application/vnd.openxmlformats-officedocument.presentationml.template.main+xml";
401 else
403 aMediaType = "application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml";
407 mPresentationFS = openFragmentStreamWithSerializer("ppt/presentation.xml", aMediaType);
409 addRelation(mPresentationFS->getOutputStream(),
410 oox::getRelationship(Relationship::THEME),
411 "theme/theme1.xml");
413 mPresentationFS->startElementNS(XML_p, XML_presentation, PNMSS, FSEND);
415 mXStatusIndicator.set(getStatusIndicator(), UNO_QUERY);
417 std::vector< PropertyValue > aProperties;
418 PropertyValue aProperty;
419 aProperty.Name = "BaseURI";
420 aProperty.Value <<= getFileUrl();
421 aProperties.push_back(aProperty);
423 exportPPT(aProperties);
425 mPresentationFS->singleElementNS(XML_p, XML_sldSz,
426 XML_cx, IS(PPTtoEMU(maDestPageSize.Width)),
427 XML_cy, IS(PPTtoEMU(maDestPageSize.Height)),
428 FSEND);
429 // for some reason if added before slides list it will not load the slides (alas with error reports) in mso
430 mPresentationFS->singleElementNS(XML_p, XML_notesSz,
431 XML_cx, IS(PPTtoEMU(maNotesPageSize.Width)),
432 XML_cy, IS(PPTtoEMU(maNotesPageSize.Height)),
433 FSEND);
435 WriteAuthors();
437 WriteVBA();
439 mPresentationFS->endElementNS(XML_p, XML_presentation);
440 mPresentationFS.reset();
441 // Free all FSHelperPtr, to flush data before committing storage
442 mpSlidesFSArray.clear();
444 commitStorage();
446 maShapeMap.clear();
447 maAuthors.clear();
449 return true;
452 ::oox::ole::VbaProject* PowerPointExport::implCreateVbaProject() const
454 return new ::oox::ole::VbaProject(getComponentContext(), getModel(), "Impress");
457 void PowerPointExport::ImplWriteBackground(const FSHelperPtr& pFS, const Reference< XPropertySet >& rXPropSet)
459 FillStyle aFillStyle(FillStyle_NONE);
460 if (ImplGetPropertyValue(rXPropSet, "FillStyle"))
461 mAny >>= aFillStyle;
463 if (aFillStyle == FillStyle_NONE ||
464 aFillStyle == FillStyle_GRADIENT ||
465 aFillStyle == FillStyle_HATCH)
466 return;
468 pFS->startElementNS(XML_p, XML_bg, FSEND);
469 pFS->startElementNS(XML_p, XML_bgPr, FSEND);
471 PowerPointShapeExport aDML(pFS, &maShapeMap, this);
472 aDML.SetBackgroundDark(mbIsBackgroundDark);
473 aDML.WriteFill(rXPropSet);
475 pFS->endElementNS(XML_p, XML_bgPr);
476 pFS->endElementNS(XML_p, XML_bg);
479 #define MAIN_GROUP \
480 "<p:nvGrpSpPr>\
481 <p:cNvPr id=\"1\" name=\"\"/>\
482 <p:cNvGrpSpPr/>\
483 <p:nvPr/>\
484 </p:nvGrpSpPr>\
485 <p:grpSpPr>\
486 <a:xfrm>\
487 <a:off x=\"0\" y=\"0\"/>\
488 <a:ext cx=\"0\" cy=\"0\"/>\
489 <a:chOff x=\"0\" y=\"0\"/>\
490 <a:chExt cx=\"0\" cy=\"0\"/>\
491 </a:xfrm>\
492 </p:grpSpPr>"
494 const char* PowerPointExport::GetSideDirection(sal_uInt8 nDirection)
496 const char* pDirection = nullptr;
498 switch (nDirection)
500 case 0:
501 pDirection = "l";
502 break;
503 case 1:
504 pDirection = "u";
505 break;
506 case 2:
507 pDirection = "r";
508 break;
509 case 3:
510 pDirection = "d";
511 break;
514 return pDirection;
517 const char* PowerPointExport::GetCornerDirection(sal_uInt8 nDirection)
519 const char* pDirection = nullptr;
521 switch (nDirection)
523 case 4:
524 pDirection = "lu";
525 break;
526 case 5:
527 pDirection = "ru";
528 break;
529 case 6:
530 pDirection = "ld";
531 break;
532 case 7:
533 pDirection = "rd";
534 break;
537 return pDirection;
540 const char* PowerPointExport::Get8Direction(sal_uInt8 nDirection)
542 const char* pDirection = GetSideDirection(nDirection);
544 if (!pDirection)
545 pDirection = GetCornerDirection(nDirection);
547 return pDirection;
550 void PowerPointExport::WriteTransition(const FSHelperPtr& pFS)
552 FadeEffect eFadeEffect = FadeEffect_NONE;
553 if (ImplGetPropertyValue(mXPagePropSet, "Effect"))
554 mAny >>= eFadeEffect;
556 sal_Int16 nTransitionType = 0, nTransitionSubtype = 0;
557 sal_Int8 nPPTTransitionType = 0;
558 sal_uInt8 nDirection = 0;
560 if (ImplGetPropertyValue(mXPagePropSet, "TransitionType") && (mAny >>= nTransitionType) &&
561 ImplGetPropertyValue(mXPagePropSet, "TransitionSubtype") && (mAny >>= nTransitionSubtype))
562 nPPTTransitionType = GetTransition(nTransitionType, nTransitionSubtype, eFadeEffect, nDirection);
564 if (!nPPTTransitionType && eFadeEffect != FadeEffect_NONE)
565 nPPTTransitionType = GetTransition(eFadeEffect, nDirection);
567 bool bOOXmlSpecificTransition = false;
569 sal_Int32 nTransition = 0;
570 const char* pDirection = nullptr;
571 const char* pOrientation = nullptr;
572 const char* pThruBlk = nullptr;
573 const char* pSpokes = nullptr;
575 char pSpokesTmp[2] = "0";
577 // p14
578 sal_Int32 nTransition14 = 0;
579 const char* pDirection14 = nullptr;
580 const char* pInverted = nullptr;
581 const char* pPattern = nullptr; // diamond or hexagon
583 //p15
584 const char* pPresetTransition = nullptr;
586 if (!nPPTTransitionType)
588 switch (nTransitionType)
590 case animations::TransitionType::BARWIPE:
592 if (nTransitionSubtype == animations::TransitionSubType::FADEOVERCOLOR)
594 nTransition = XML_cut;
595 pThruBlk = "true";
596 bOOXmlSpecificTransition = true;
598 break;
600 case animations::TransitionType::MISCSHAPEWIPE:
602 switch (nTransitionSubtype)
604 case animations::TransitionSubType::TOPTOBOTTOM: // Turn around
605 nTransition = XML_fade;
606 nTransition14 = XML_flip;
607 pDirection14 = "l";
608 bOOXmlSpecificTransition = true;
609 break;
610 case animations::TransitionSubType::BOTTOMRIGHT: // Rochade
611 nTransition = XML_fade;
612 nTransition14 = XML_switch;
613 pDirection14 = "r";
614 bOOXmlSpecificTransition = true;
615 break;
616 case animations::TransitionSubType::VERTICAL: // Vortex
617 nTransition = XML_fade;
618 nTransition14 = XML_vortex;
619 bOOXmlSpecificTransition = true;
620 break;
621 case animations::TransitionSubType::HORIZONTAL: // Ripple
622 nTransition = XML_fade;
623 nTransition14 = XML_ripple;
624 bOOXmlSpecificTransition = true;
625 break;
626 case animations::TransitionSubType::LEFTTORIGHT: // Fall
627 nTransition = XML_fade;
628 pPresetTransition = "fallOver";
629 bOOXmlSpecificTransition = true;
630 break;
631 case animations::TransitionSubType::CORNERSIN: // Inside turning cube
632 pInverted = "true";
633 [[fallthrough]];
634 case animations::TransitionSubType::CORNERSOUT: // Outside turning cube
635 nTransition = XML_fade;
636 nTransition14 = XML_prism;
637 bOOXmlSpecificTransition = true;
638 break;
639 case animations::TransitionSubType::DIAMOND: // Glitter
640 nTransition = XML_fade;
641 nTransition14 = XML_glitter;
642 pDirection14 = "l";
643 pPattern = "hexagon";
644 bOOXmlSpecificTransition = true;
645 break;
646 case animations::TransitionSubType::HEART: // Honeycomb
647 nTransition = XML_fade;
648 nTransition14 = XML_honeycomb;
649 bOOXmlSpecificTransition = true;
650 break;
652 break;
657 AnimationSpeed animationSpeed = AnimationSpeed_MEDIUM;
658 const char* speed = nullptr;
659 sal_Int32 advanceTiming = -1;
660 sal_Int32 changeType = 0;
662 sal_Int32 nTransitionDuration = -1;
663 bool isTransitionDurationSet = false;
665 // try to use TransitionDuration instead of old Speed property
666 if (ImplGetPropertyValue(mXPagePropSet, "TransitionDuration"))
668 double fTransitionDuration = -1.0;
669 mAny >>= fTransitionDuration;
670 if (fTransitionDuration >= 0)
672 nTransitionDuration = fTransitionDuration * 1000.0;
674 // override values because in MS formats meaning of fast/medium/slow is different
675 if (nTransitionDuration <= 500)
677 // fast is default
678 speed = nullptr;
680 else if (nTransitionDuration >= 1000)
682 speed = "slow";
684 else
686 speed = "med";
689 bool isStandardValue = nTransitionDuration == 500
690 || nTransitionDuration == 750
691 || nTransitionDuration == 1000;
693 if(!isStandardValue)
694 isTransitionDurationSet = true;
697 else if (ImplGetPropertyValue(mXPagePropSet, "Speed"))
699 mAny >>= animationSpeed;
701 switch (animationSpeed)
703 default:
704 case AnimationSpeed_MEDIUM:
705 speed = "med";
706 break;
707 case AnimationSpeed_SLOW:
708 speed = "slow";
709 break;
710 case AnimationSpeed_FAST:
711 break;
715 // check if we resolved what transition to export or time is set
716 if (!nPPTTransitionType && !bOOXmlSpecificTransition && !isTransitionDurationSet)
717 return;
719 if (ImplGetPropertyValue(mXPagePropSet, "Change"))
720 mAny >>= changeType;
722 // 1 means automatic, 2 half automatic - not sure what it means - at least I don't see it in UI
723 if (changeType == 1 && ImplGetPropertyValue(mXPagePropSet, "Duration"))
724 mAny >>= advanceTiming;
726 if (!bOOXmlSpecificTransition)
728 switch (nPPTTransitionType)
730 case PPT_TRANSITION_TYPE_BLINDS:
731 nTransition = XML_blinds;
732 pDirection = (nDirection == 0) ? "vert" : "horz";
733 break;
734 case PPT_TRANSITION_TYPE_CHECKER:
735 nTransition = XML_checker;
736 pDirection = (nDirection == 1) ? "vert" : "horz";
737 break;
738 case PPT_TRANSITION_TYPE_CIRCLE:
739 nTransition = XML_circle;
740 break;
741 case PPT_TRANSITION_TYPE_COMB:
742 nTransition = XML_comb;
743 pDirection = (nDirection == 1) ? "vert" : "horz";
744 break;
745 case PPT_TRANSITION_TYPE_COVER:
746 nTransition = XML_cover;
747 pDirection = Get8Direction(nDirection);
748 break;
749 case PPT_TRANSITION_TYPE_DIAMOND:
750 nTransition = XML_diamond;
751 break;
752 case PPT_TRANSITION_TYPE_DISSOLVE:
753 nTransition = XML_dissolve;
754 break;
755 case PPT_TRANSITION_TYPE_FADE:
756 nTransition = XML_fade;
757 pThruBlk = "true";
758 break;
759 case PPT_TRANSITION_TYPE_SMOOTHFADE:
760 nTransition = XML_fade;
761 break;
762 case PPT_TRANSITION_TYPE_NEWSFLASH:
763 nTransition = XML_newsflash;
764 break;
765 case PPT_TRANSITION_TYPE_PLUS:
766 nTransition = XML_plus;
767 break;
768 case PPT_TRANSITION_TYPE_PULL:
769 nTransition = XML_pull;
770 pDirection = Get8Direction(nDirection);
771 break;
772 case PPT_TRANSITION_TYPE_PUSH:
773 nTransition = XML_push;
774 pDirection = GetSideDirection(nDirection);
775 break;
776 case PPT_TRANSITION_TYPE_RANDOM:
777 nTransition = XML_random;
778 break;
779 case PPT_TRANSITION_TYPE_RANDOM_BARS:
780 nTransition = XML_randomBar;
781 pDirection = (nDirection == 1) ? "vert" : "horz";
782 break;
783 case PPT_TRANSITION_TYPE_SPLIT:
784 nTransition = XML_split;
785 pDirection = (nDirection & 1) ? "in" : "out";
786 pOrientation = (nDirection < 2) ? "horz" : "vert";
787 break;
788 case PPT_TRANSITION_TYPE_STRIPS:
789 nTransition = XML_strips;
790 pDirection = GetCornerDirection(nDirection);
791 break;
792 case PPT_TRANSITION_TYPE_WEDGE:
793 nTransition = XML_wedge;
794 break;
795 case PPT_TRANSITION_TYPE_WHEEL:
796 nTransition = XML_wheel;
797 if (nDirection != 4 && nDirection <= 9)
799 pSpokesTmp[0] = '0' + nDirection;
800 pSpokes = pSpokesTmp;
802 break;
803 case PPT_TRANSITION_TYPE_WIPE:
804 nTransition = XML_wipe;
805 pDirection = GetSideDirection(nDirection);
806 break;
807 case PPT_TRANSITION_TYPE_ZOOM:
808 nTransition = XML_zoom;
809 pDirection = (nDirection == 1) ? "in" : "out";
810 break;
811 // coverity[dead_error_line] - following conditions exist to avoid compiler warning
812 case PPT_TRANSITION_TYPE_NONE:
813 default:
814 nTransition = 0;
815 break;
819 bool isAdvanceTimingSet = advanceTiming != -1;
820 if (nTransition14 || pPresetTransition || isTransitionDurationSet)
822 const char* pRequiresNS = (nTransition14 || isTransitionDurationSet) ? "p14" : "p15";
824 pFS->startElement(FSNS(XML_mc, XML_AlternateContent), FSEND);
825 pFS->startElement(FSNS(XML_mc, XML_Choice), XML_Requires, pRequiresNS, FSEND);
827 if(isTransitionDurationSet && isAdvanceTimingSet)
829 pFS->startElementNS(XML_p, XML_transition,
830 XML_spd, speed,
831 XML_advTm, I32S(advanceTiming * 1000),
832 FSNS(XML_p14, XML_dur), I32S(nTransitionDuration),
833 FSEND);
835 else if(isTransitionDurationSet)
837 pFS->startElementNS(XML_p, XML_transition,
838 XML_spd, speed,
839 FSNS(XML_p14, XML_dur), I32S(nTransitionDuration),
840 FSEND);
842 else if(isAdvanceTimingSet)
844 pFS->startElementNS(XML_p, XML_transition,
845 XML_spd, speed,
846 XML_advTm, I32S(advanceTiming * 1000),
847 FSEND);
849 else
851 pFS->startElementNS(XML_p, XML_transition,
852 XML_spd, speed,
853 FSEND);
856 if (nTransition14)
858 pFS->singleElementNS(XML_p14, nTransition14,
859 XML_isInverted, pInverted,
860 XML_dir, pDirection14,
861 XML_pattern, pPattern,
862 FSEND);
864 else if (pPresetTransition)
866 pFS->singleElementNS(XML_p15, XML_prstTrans,
867 XML_prst, pPresetTransition,
868 FSEND);
870 else if (isTransitionDurationSet && nTransition)
872 pFS->singleElementNS(XML_p, nTransition,
873 XML_dir, pDirection,
874 XML_orient, pOrientation,
875 XML_spokes, pSpokes,
876 XML_thruBlk, pThruBlk,
877 FSEND);
880 pFS->endElement(FSNS(XML_p, XML_transition));
882 pFS->endElement(FSNS(XML_mc, XML_Choice));
883 pFS->startElement(FSNS(XML_mc, XML_Fallback), FSEND);
886 pFS->startElementNS(XML_p, XML_transition,
887 XML_spd, speed,
888 XML_advTm, isAdvanceTimingSet ? I32S(advanceTiming * 1000) : nullptr,
889 FSEND);
891 if (nTransition)
893 pFS->singleElementNS(XML_p, nTransition,
894 XML_dir, pDirection,
895 XML_orient, pOrientation,
896 XML_spokes, pSpokes,
897 XML_thruBlk, pThruBlk,
898 FSEND);
901 pFS->endElementNS(XML_p, XML_transition);
903 if (nTransition14 || pPresetTransition || isTransitionDurationSet)
905 pFS->endElement(FSNS(XML_mc, XML_Fallback));
906 pFS->endElement(FSNS(XML_mc, XML_AlternateContent));
910 static OUString lcl_GetInitials(const OUString& sName)
912 OUStringBuffer sRet;
914 if (!sName.isEmpty())
916 sRet.append(sName[0]);
917 sal_Int32 nStart = 0, nOffset;
919 while ((nOffset = sName.indexOf(' ', nStart)) != -1)
921 if (nOffset + 1 < sName.getLength())
922 sRet.append(sName[ nOffset + 1 ]);
923 nStart = nOffset + 1;
927 return sRet.makeStringAndClear();
930 void PowerPointExport::WriteAuthors()
932 if (maAuthors.empty())
933 return;
935 FSHelperPtr pFS = openFragmentStreamWithSerializer("ppt/commentAuthors.xml",
936 "application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml");
937 addRelation(mPresentationFS->getOutputStream(),
938 oox::getRelationship(Relationship::COMMENTAUTHORS),
939 "commentAuthors.xml");
941 pFS->startElementNS(XML_p, XML_cmAuthorLst,
942 FSNS(XML_xmlns, XML_p), OUStringToOString(this->getNamespaceURL(OOX_NS(ppt)), RTL_TEXTENCODING_UTF8),
943 FSEND);
945 for (const AuthorsMap::value_type& i : maAuthors)
947 pFS->singleElementNS(XML_p, XML_cmAuthor,
948 XML_id, I32S(i.second.nId),
949 XML_name, USS(i.first),
950 XML_initials, USS(lcl_GetInitials(i.first)),
951 XML_lastIdx, I32S(i.second.nLastIndex),
952 XML_clrIdx, I32S(i.second.nId),
953 FSEND);
956 pFS->endElementNS(XML_p, XML_cmAuthorLst);
959 sal_Int32 PowerPointExport::GetAuthorIdAndLastIndex(const OUString& sAuthor, sal_Int32& nLastIndex)
961 if (maAuthors.count(sAuthor) <= 0)
963 struct AuthorComments aAuthorComments;
965 aAuthorComments.nId = maAuthors.size();
966 aAuthorComments.nLastIndex = 0;
968 maAuthors[ sAuthor ] = aAuthorComments;
971 nLastIndex = ++maAuthors[ sAuthor ].nLastIndex;
973 return maAuthors[ sAuthor ].nId;
976 bool PowerPointExport::WriteComments(sal_uInt32 nPageNum)
978 Reference< XAnnotationAccess > xAnnotationAccess(mXDrawPage, uno::UNO_QUERY);
979 if (xAnnotationAccess.is())
981 Reference< XAnnotationEnumeration > xAnnotationEnumeration(xAnnotationAccess->createAnnotationEnumeration());
983 if (xAnnotationEnumeration->hasMoreElements())
985 FSHelperPtr pFS = openFragmentStreamWithSerializer(OUStringBuffer()
986 .append("ppt/comments/comment")
987 .append(static_cast<sal_Int32>(nPageNum) + 1)
988 .append(".xml")
989 .makeStringAndClear(),
990 "application/vnd.openxmlformats-officedocument.presentationml.comments+xml");
992 pFS->startElementNS(XML_p, XML_cmLst,
993 FSNS(XML_xmlns, XML_p), OUStringToOString(this->getNamespaceURL(OOX_NS(ppt)), RTL_TEXTENCODING_UTF8),
994 FSEND);
998 Reference< XAnnotation > xAnnotation(xAnnotationEnumeration->nextElement());
999 DateTime aDateTime(xAnnotation->getDateTime());
1000 RealPoint2D aRealPoint2D(xAnnotation->getPosition());
1001 Reference< XText > xText(xAnnotation->getTextRange());
1002 sal_Int32 nLastIndex;
1003 sal_Int32 nId = GetAuthorIdAndLastIndex(xAnnotation->getAuthor(), nLastIndex);
1004 char cDateTime[32];
1006 snprintf(cDateTime, 31, "%02d-%02d-%02dT%02d:%02d:%02d.%09" SAL_PRIuUINT32, aDateTime.Year, aDateTime.Month, aDateTime.Day, aDateTime.Hours, aDateTime.Minutes, aDateTime.Seconds, aDateTime.NanoSeconds);
1008 pFS->startElementNS(XML_p, XML_cm,
1009 XML_authorId, I32S(nId),
1010 XML_dt, cDateTime,
1011 XML_idx, I32S(nLastIndex),
1012 FSEND);
1014 pFS->singleElementNS(XML_p, XML_pos,
1015 XML_x, I64S(static_cast<sal_Int64>((57600*aRealPoint2D.X + 1270)/2540.0)),
1016 XML_y, I64S(static_cast<sal_Int64>((57600*aRealPoint2D.Y + 1270)/2540.0)),
1017 FSEND);
1019 pFS->startElementNS(XML_p, XML_text,
1020 FSEND);
1021 pFS->write(xText->getString());
1022 pFS->endElementNS(XML_p, XML_text);
1024 pFS->endElementNS(XML_p, XML_cm);
1027 while (xAnnotationEnumeration->hasMoreElements());
1029 pFS->endElementNS(XML_p, XML_cmLst);
1031 return true;
1035 return false;
1038 void PowerPointExport::WriteVBA()
1040 if (!mbPptm)
1041 return;
1043 uno::Reference<document::XStorageBasedDocument> xStorageBasedDocument(getModel(), uno::UNO_QUERY);
1044 if (!xStorageBasedDocument.is())
1045 return;
1047 uno::Reference<embed::XStorage> xDocumentStorage(xStorageBasedDocument->getDocumentStorage(), uno::UNO_QUERY);
1048 OUString aMacrosName("_MS_VBA_Macros");
1049 if (!xDocumentStorage.is() || !xDocumentStorage->hasByName(aMacrosName))
1050 return;
1052 const sal_Int32 nOpenMode = embed::ElementModes::READ;
1053 uno::Reference<io::XInputStream> xMacrosStream(xDocumentStorage->openStreamElement(aMacrosName, nOpenMode), uno::UNO_QUERY);
1054 if (!xMacrosStream.is())
1055 return;
1057 uno::Reference<io::XOutputStream> xOutputStream = openFragmentStream("ppt/vbaProject.bin", "application/vnd.ms-office.vbaProject");
1058 comphelper::OStorageHelper::CopyInputToOutput(xMacrosStream, xOutputStream);
1060 // Write the relationship.
1061 addRelation(mPresentationFS->getOutputStream(), oox::getRelationship(Relationship::VBAPROJECT), "vbaProject.bin");
1064 void PowerPointExport::ImplWriteSlide(sal_uInt32 nPageNum, sal_uInt32 nMasterNum, sal_uInt16 /* nMode */,
1065 bool bHasBackground, Reference< XPropertySet > const& aXBackgroundPropSet)
1067 SAL_INFO("sd.eppt", "write slide: " << nPageNum << "\n----------------");
1069 // slides list
1070 if (nPageNum == 0)
1071 mPresentationFS->startElementNS(XML_p, XML_sldIdLst, FSEND);
1073 // add explicit relation of presentation to this slide
1074 OUString sRelId = addRelation(mPresentationFS->getOutputStream(),
1075 oox::getRelationship(Relationship::SLIDE),
1076 OUStringBuffer()
1077 .append("slides/slide")
1078 .append(static_cast<sal_Int32>(nPageNum) + 1)
1079 .append(".xml")
1080 .makeStringAndClear());
1082 mPresentationFS->singleElementNS(XML_p, XML_sldId,
1083 XML_id, I32S(GetNewSlideId()),
1084 FSNS(XML_r, XML_id), USS(sRelId),
1085 FSEND);
1087 if (nPageNum == mnPages - 1)
1088 mPresentationFS->endElementNS(XML_p, XML_sldIdLst);
1090 FSHelperPtr pFS = openFragmentStreamWithSerializer(OUStringBuffer()
1091 .append("ppt/slides/slide")
1092 .append(static_cast<sal_Int32>(nPageNum) + 1)
1093 .append(".xml")
1094 .makeStringAndClear(),
1095 "application/vnd.openxmlformats-officedocument.presentationml.slide+xml");
1097 if (mpSlidesFSArray.size() < mnPages)
1098 mpSlidesFSArray.resize(mnPages);
1099 mpSlidesFSArray[ nPageNum ] = pFS;
1101 const char* pShow = nullptr;
1103 if (ImplGetPropertyValue(mXPagePropSet, "Visible"))
1105 bool bShow(false);
1106 if ((mAny >>= bShow) && !bShow)
1107 pShow = "0";
1110 pFS->startElementNS(XML_p, XML_sld, PNMSS,
1111 XML_show, pShow,
1112 FSEND);
1114 pFS->startElementNS(XML_p, XML_cSld, FSEND);
1116 // background
1117 if (bHasBackground)
1119 ImplWriteBackground(pFS, aXBackgroundPropSet);
1122 WriteShapeTree(pFS, NORMAL, false);
1124 pFS->endElementNS(XML_p, XML_cSld);
1126 WriteTransition(pFS);
1127 WriteAnimations(pFS, mXDrawPage, *this);
1129 pFS->endElementNS(XML_p, XML_sld);
1131 // add implicit relation to slide layout
1132 addRelation(pFS->getOutputStream(),
1133 oox::getRelationship(Relationship::SLIDELAYOUT),
1134 OUStringBuffer()
1135 .append("../slideLayouts/slideLayout")
1136 .append(GetLayoutFileId(GetPPTXLayoutId(GetLayoutOffset(mXPagePropSet)), nMasterNum))
1137 .append(".xml")
1138 .makeStringAndClear());
1140 if (WriteComments(nPageNum))
1141 // add implicit relation to slide comments
1142 addRelation(pFS->getOutputStream(),
1143 oox::getRelationship(Relationship::COMMENTS),
1144 OUStringBuffer()
1145 .append("../comments/comment")
1146 .append(static_cast<sal_Int32>(nPageNum) + 1)
1147 .append(".xml")
1148 .makeStringAndClear());
1150 SAL_INFO("sd.eppt", "----------------");
1153 void PowerPointExport::ImplWriteNotes(sal_uInt32 nPageNum)
1155 if (!mbCreateNotes || !ContainsOtherShapeThanPlaceholders())
1156 return;
1158 SAL_INFO("sd.eppt", "write Notes " << nPageNum << "\n----------------");
1160 FSHelperPtr pFS = openFragmentStreamWithSerializer(OUStringBuffer()
1161 .append("ppt/notesSlides/notesSlide")
1162 .append(static_cast<sal_Int32>(nPageNum) + 1)
1163 .append(".xml")
1164 .makeStringAndClear(),
1165 "application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml");
1167 pFS->startElementNS(XML_p, XML_notes, PNMSS, FSEND);
1169 pFS->startElementNS(XML_p, XML_cSld, FSEND);
1171 WriteShapeTree(pFS, NOTICE, false);
1173 pFS->endElementNS(XML_p, XML_cSld);
1175 pFS->endElementNS(XML_p, XML_notes);
1177 // add implicit relation to slide
1178 addRelation(pFS->getOutputStream(),
1179 oox::getRelationship(Relationship::SLIDE),
1180 OUStringBuffer()
1181 .append("../slides/slide")
1182 .append(static_cast<sal_Int32>(nPageNum) + 1)
1183 .append(".xml")
1184 .makeStringAndClear());
1186 // add slide implicit relation to notes
1187 if (nPageNum < mpSlidesFSArray.size())
1188 addRelation(mpSlidesFSArray[ nPageNum ]->getOutputStream(),
1189 oox::getRelationship(Relationship::NOTESSLIDE),
1190 OUStringBuffer()
1191 .append("../notesSlides/notesSlide")
1192 .append(static_cast<sal_Int32>(nPageNum) + 1)
1193 .append(".xml")
1194 .makeStringAndClear());
1196 // add implicit relation to notes master
1197 addRelation(pFS->getOutputStream(),
1198 oox::getRelationship(Relationship::NOTESMASTER),
1199 "../notesMasters/notesMaster1.xml");
1201 SAL_INFO("sd.eppt", "-----------------");
1204 void PowerPointExport::AddLayoutIdAndRelation(const FSHelperPtr& pFS, sal_Int32 nLayoutFileId)
1206 // add implicit relation of slide master to slide layout
1207 OUString sRelId = addRelation(pFS->getOutputStream(),
1208 oox::getRelationship(Relationship::SLIDELAYOUT),
1209 OUStringBuffer()
1210 .append("../slideLayouts/slideLayout")
1211 .append(nLayoutFileId)
1212 .append(".xml")
1213 .makeStringAndClear());
1215 pFS->singleElementNS(XML_p, XML_sldLayoutId,
1216 XML_id, I64S(GetNewSlideMasterId()),
1217 FSNS(XML_r, XML_id), USS(sRelId),
1218 FSEND);
1221 void PowerPointExport::ImplWriteSlideMaster(sal_uInt32 nPageNum, Reference< XPropertySet > const& aXBackgroundPropSet)
1223 SAL_INFO("sd.eppt", "write master slide: " << nPageNum << "\n--------------");
1225 // slides list
1226 if (nPageNum == 0)
1227 mPresentationFS->startElementNS(XML_p, XML_sldMasterIdLst, FSEND);
1229 OUString sRelId = addRelation(mPresentationFS->getOutputStream(),
1230 oox::getRelationship(Relationship::SLIDEMASTER),
1231 OUStringBuffer()
1232 .append("slideMasters/slideMaster")
1233 .append(static_cast<sal_Int32>(nPageNum) + 1)
1234 .append(".xml")
1235 .makeStringAndClear());
1237 mPresentationFS->singleElementNS(XML_p, XML_sldMasterId,
1238 XML_id, OString::number(GetNewSlideMasterId()).getStr(),
1239 FSNS(XML_r, XML_id), USS(sRelId),
1240 FSEND);
1242 if (nPageNum == mnMasterPages - 1)
1243 mPresentationFS->endElementNS(XML_p, XML_sldMasterIdLst);
1245 FSHelperPtr pFS =
1246 openFragmentStreamWithSerializer(OUStringBuffer()
1247 .append("ppt/slideMasters/slideMaster")
1248 .append(static_cast<sal_Int32>(nPageNum) + 1)
1249 .append(".xml")
1250 .makeStringAndClear(),
1251 "application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml");
1253 // write theme per master
1254 WriteTheme(nPageNum);
1256 // add implicit relation to the presentation theme
1257 addRelation(pFS->getOutputStream(),
1258 oox::getRelationship(Relationship::THEME),
1259 OUStringBuffer()
1260 .append("../theme/theme")
1261 .append(static_cast<sal_Int32>(nPageNum) + 1)
1262 .append(".xml")
1263 .makeStringAndClear());
1265 pFS->startElementNS(XML_p, XML_sldMaster, PNMSS, FSEND);
1267 pFS->startElementNS(XML_p, XML_cSld, FSEND);
1269 ImplWriteBackground(pFS, aXBackgroundPropSet);
1270 WriteShapeTree(pFS, MASTER, true);
1272 pFS->endElementNS(XML_p, XML_cSld);
1274 // color map - now it uses colors from hardcoded theme, once we eventually generate theme, this might need update
1275 pFS->singleElementNS(XML_p, XML_clrMap,
1276 XML_bg1, "lt1",
1277 XML_bg2, "lt2",
1278 XML_tx1, "dk1",
1279 XML_tx2, "dk2",
1280 XML_accent1, "accent1",
1281 XML_accent2, "accent2",
1282 XML_accent3, "accent3",
1283 XML_accent4, "accent4",
1284 XML_accent5, "accent5",
1285 XML_accent6, "accent6",
1286 XML_hlink, "hlink",
1287 XML_folHlink, "folHlink",
1288 FSEND);
1290 // use master's id type as they have same range, mso does that as well
1291 pFS->startElementNS(XML_p, XML_sldLayoutIdLst, FSEND);
1293 for (int i = 0; i < LAYOUT_SIZE; i++)
1295 sal_Int32 nLayoutFileId = GetLayoutFileId(i, nPageNum);
1296 if (nLayoutFileId > 0)
1298 AddLayoutIdAndRelation(pFS, nLayoutFileId);
1300 else
1302 ImplWritePPTXLayout(i, nPageNum);
1303 AddLayoutIdAndRelation(pFS, GetLayoutFileId(i, nPageNum));
1307 pFS->endElementNS(XML_p, XML_sldLayoutIdLst);
1309 pFS->endElementNS(XML_p, XML_sldMaster);
1311 SAL_INFO("sd.eppt", "----------------");
1314 sal_Int32 PowerPointExport::GetLayoutFileId(sal_Int32 nOffset, sal_uInt32 nMasterNum)
1316 SAL_INFO("sd.eppt", "GetLayoutFileId offset: " << nOffset << " master: " << nMasterNum);
1317 if (mLayoutInfo[ nOffset ].mnFileIdArray.size() <= nMasterNum)
1318 return 0;
1320 return mLayoutInfo[ nOffset ].mnFileIdArray[ nMasterNum ];
1323 void PowerPointExport::ImplWritePPTXLayout(sal_Int32 nOffset, sal_uInt32 nMasterNum)
1325 SAL_INFO("sd.eppt", "write layout: " << nOffset);
1327 Reference< drawing::XDrawPagesSupplier > xDPS(getModel(), uno::UNO_QUERY);
1328 Reference< drawing::XDrawPages > xDrawPages(xDPS->getDrawPages(), uno::UNO_QUERY);
1329 Reference< drawing::XDrawPage > xSlide;
1330 Reference< container::XIndexAccess > xIndexAccess(xDrawPages, uno::UNO_QUERY);
1332 xSlide = xDrawPages->insertNewByIndex(xIndexAccess->getCount());
1334 #ifdef DEBUG
1335 if (xSlide.is())
1336 printf("new page created\n");
1337 #endif
1339 Reference< beans::XPropertySet > xPropSet(xSlide, uno::UNO_QUERY);
1340 xPropSet->setPropertyValue("Layout", makeAny(short(aLayoutInfo[ nOffset ].nType)));
1341 #if OSL_DEBUG_LEVEL > 1
1342 dump_pset(xPropSet);
1343 #endif
1344 mXPagePropSet.set(xSlide, UNO_QUERY);
1345 mXShapes.set(xSlide, UNO_QUERY);
1347 if (mLayoutInfo[ nOffset ].mnFileIdArray.size() < mnMasterPages)
1349 mLayoutInfo[ nOffset ].mnFileIdArray.resize(mnMasterPages);
1352 if (mLayoutInfo[ nOffset ].mnFileIdArray[ nMasterNum ] != 0)
1353 return;
1355 FSHelperPtr pFS
1356 = openFragmentStreamWithSerializer(OUStringBuffer()
1357 .append("ppt/slideLayouts/slideLayout")
1358 .append(mnLayoutFileIdMax)
1359 .append(".xml")
1360 .makeStringAndClear(),
1361 "application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml");
1363 // add implicit relation of slide layout to slide master
1364 addRelation(pFS->getOutputStream(),
1365 oox::getRelationship(Relationship::SLIDEMASTER),
1366 OUStringBuffer()
1367 .append("../slideMasters/slideMaster")
1368 .append(static_cast<sal_Int32>(nMasterNum) + 1)
1369 .append(".xml")
1370 .makeStringAndClear());
1372 pFS->startElementNS(XML_p, XML_sldLayout,
1373 PNMSS,
1374 XML_type, aLayoutInfo[ nOffset ].sType,
1375 XML_preserve, "1",
1376 FSEND);
1378 pFS->startElementNS(XML_p, XML_cSld,
1379 XML_name, aLayoutInfo[ nOffset ].sName,
1380 FSEND);
1381 //pFS->write( MINIMAL_SPTREE ); // TODO: write actual shape tree
1382 WriteShapeTree(pFS, LAYOUT, true);
1384 pFS->endElementNS(XML_p, XML_cSld);
1386 pFS->endElementNS(XML_p, XML_sldLayout);
1388 mLayoutInfo[ nOffset ].mnFileIdArray[ nMasterNum ] = mnLayoutFileIdMax;
1390 mnLayoutFileIdMax ++;
1392 xDrawPages->remove(xSlide);
1395 void PowerPointExport::WriteShapeTree(const FSHelperPtr& pFS, PageType ePageType, bool bMaster)
1397 PowerPointShapeExport aDML(pFS, &maShapeMap, this);
1398 aDML.SetMaster(bMaster);
1399 aDML.SetPageType(ePageType);
1400 aDML.SetBackgroundDark(mbIsBackgroundDark);
1402 pFS->startElementNS(XML_p, XML_spTree, FSEND);
1403 pFS->write(MAIN_GROUP);
1405 ResetGroupTable(mXShapes->getCount());
1407 while (GetNextGroupEntry())
1410 sal_uInt32 nGroups = GetGroupsClosed();
1411 for (sal_uInt32 i = 0; i < nGroups; i++)
1413 SAL_INFO("sd.eppt", "leave group");
1416 if (GetShapeByIndex(GetCurrentGroupIndex(), true))
1418 SAL_INFO("sd.eppt", "mType: " << mType);
1419 aDML.WriteShape(mXShape);
1423 pFS->endElementNS(XML_p, XML_spTree);
1426 ShapeExport& PowerPointShapeExport::WritePageShape(const Reference< XShape >& xShape, PageType ePageType, bool bPresObj)
1428 if ((ePageType == NOTICE && bPresObj) || ePageType == LAYOUT || ePageType == MASTER)
1429 return WritePlaceholderShape(xShape, SlideImage);
1431 return WriteTextShape(xShape);
1434 bool PowerPointShapeExport::WritePlaceholder(const Reference< XShape >& xShape, PlaceholderType ePlaceholder, bool bMaster)
1436 SAL_INFO("sd.eppt", "WritePlaceholder " << bMaster << " " << ShapeExport::NonEmptyText(xShape));
1437 if (bMaster && ShapeExport::NonEmptyText(xShape))
1439 WritePlaceholderShape(xShape, ePlaceholder);
1441 return true;
1444 return false;
1447 ShapeExport& PowerPointShapeExport::WritePlaceholderShape(const Reference< XShape >& xShape, PlaceholderType ePlaceholder)
1449 mpFS->startElementNS(XML_p, XML_sp, FSEND);
1451 // non visual shape properties
1452 mpFS->startElementNS(XML_p, XML_nvSpPr, FSEND);
1453 const OString aPlaceholderID("PlaceHolder " + OString::number(mnShapeIdMax++));
1454 WriteNonVisualDrawingProperties(xShape, aPlaceholderID.getStr());
1455 mpFS->startElementNS(XML_p, XML_cNvSpPr, FSEND);
1456 mpFS->singleElementNS(XML_a, XML_spLocks, XML_noGrp, "1", FSEND);
1457 mpFS->endElementNS(XML_p, XML_cNvSpPr);
1458 mpFS->startElementNS(XML_p, XML_nvPr, FSEND);
1460 const char* pType = nullptr;
1461 switch (ePlaceholder)
1463 case SlideImage:
1464 pType = "sldImg";
1465 break;
1466 case Notes:
1467 pType = "body";
1468 break;
1469 case Header:
1470 pType = "hdr";
1471 break;
1472 case Footer:
1473 pType = "ftr";
1474 break;
1475 case SlideNumber:
1476 pType = "sldNum";
1477 break;
1478 case DateAndTime:
1479 pType = "dt";
1480 break;
1481 case Outliner:
1482 pType = "body";
1483 break;
1484 case Title:
1485 pType = "title";
1486 break;
1487 case Subtitle:
1488 pType = "subTitle";
1489 break;
1490 default:
1491 SAL_INFO("sd.eppt", "warning: unhandled placeholder type: " << ePlaceholder);
1493 SAL_INFO("sd.eppt", "write placeholder " << pType);
1494 mpFS->singleElementNS(XML_p, XML_ph, XML_type, pType, FSEND);
1495 mpFS->endElementNS(XML_p, XML_nvPr);
1496 mpFS->endElementNS(XML_p, XML_nvSpPr);
1498 // visual shape properties
1499 mpFS->startElementNS(XML_p, XML_spPr, FSEND);
1500 WriteShapeTransformation(xShape, XML_a);
1501 WritePresetShape("rect");
1502 Reference< XPropertySet > xProps(xShape, UNO_QUERY);
1503 if (xProps.is())
1504 WriteBlipFill(xProps, "Graphic");
1505 mpFS->endElementNS(XML_p, XML_spPr);
1507 WriteTextBox(xShape, XML_p);
1509 mpFS->endElementNS(XML_p, XML_sp);
1511 return *this;
1514 #define SYS_COLOR_SCHEMES " <a:dk1>\
1515 <a:sysClr val=\"windowText\" lastClr=\"000000\"/>\
1516 </a:dk1>\
1517 <a:lt1>\
1518 <a:sysClr val=\"window\" lastClr=\"FFFFFF\"/>\
1519 </a:lt1>"
1521 #define MINIMAL_THEME " <a:fontScheme name=\"Office\">\
1522 <a:majorFont>\
1523 <a:latin typeface=\"Arial\"/>\
1524 <a:ea typeface=\"DejaVu Sans\"/>\
1525 <a:cs typeface=\"DejaVu Sans\"/>\
1526 </a:majorFont>\
1527 <a:minorFont>\
1528 <a:latin typeface=\"Arial\"/>\
1529 <a:ea typeface=\"DejaVu Sans\"/>\
1530 <a:cs typeface=\"DejaVu Sans\"/>\
1531 </a:minorFont>\
1532 </a:fontScheme>\
1533 <a:fmtScheme name=\"Office\">\
1534 <a:fillStyleLst>\
1535 <a:solidFill>\
1536 <a:schemeClr val=\"phClr\"/>\
1537 </a:solidFill>\
1538 <a:gradFill rotWithShape=\"1\">\
1539 <a:gsLst>\
1540 <a:gs pos=\"0\">\
1541 <a:schemeClr val=\"phClr\">\
1542 <a:tint val=\"50000\"/>\
1543 <a:satMod val=\"300000\"/>\
1544 </a:schemeClr>\
1545 </a:gs>\
1546 <a:gs pos=\"35000\">\
1547 <a:schemeClr val=\"phClr\">\
1548 <a:tint val=\"37000\"/>\
1549 <a:satMod val=\"300000\"/>\
1550 </a:schemeClr>\
1551 </a:gs>\
1552 <a:gs pos=\"100000\">\
1553 <a:schemeClr val=\"phClr\">\
1554 <a:tint val=\"15000\"/>\
1555 <a:satMod val=\"350000\"/>\
1556 </a:schemeClr>\
1557 </a:gs>\
1558 </a:gsLst>\
1559 <a:lin ang=\"16200000\" scaled=\"1\"/>\
1560 </a:gradFill>\
1561 <a:gradFill rotWithShape=\"1\">\
1562 <a:gsLst>\
1563 <a:gs pos=\"0\">\
1564 <a:schemeClr val=\"phClr\">\
1565 <a:shade val=\"51000\"/>\
1566 <a:satMod val=\"130000\"/>\
1567 </a:schemeClr>\
1568 </a:gs>\
1569 <a:gs pos=\"80000\">\
1570 <a:schemeClr val=\"phClr\">\
1571 <a:shade val=\"93000\"/>\
1572 <a:satMod val=\"130000\"/>\
1573 </a:schemeClr>\
1574 </a:gs>\
1575 <a:gs pos=\"100000\">\
1576 <a:schemeClr val=\"phClr\">\
1577 <a:shade val=\"94000\"/>\
1578 <a:satMod val=\"135000\"/>\
1579 </a:schemeClr>\
1580 </a:gs>\
1581 </a:gsLst>\
1582 <a:lin ang=\"16200000\" scaled=\"0\"/>\
1583 </a:gradFill>\
1584 </a:fillStyleLst>\
1585 <a:lnStyleLst>\
1586 <a:ln w=\"9525\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\
1587 <a:solidFill>\
1588 <a:schemeClr val=\"phClr\">\
1589 <a:shade val=\"95000\"/>\
1590 <a:satMod val=\"105000\"/>\
1591 </a:schemeClr>\
1592 </a:solidFill>\
1593 <a:prstDash val=\"solid\"/>\
1594 </a:ln>\
1595 <a:ln w=\"25400\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\
1596 <a:solidFill>\
1597 <a:schemeClr val=\"phClr\"/>\
1598 </a:solidFill>\
1599 <a:prstDash val=\"solid\"/>\
1600 </a:ln>\
1601 <a:ln w=\"38100\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\
1602 <a:solidFill>\
1603 <a:schemeClr val=\"phClr\"/>\
1604 </a:solidFill>\
1605 <a:prstDash val=\"solid\"/>\
1606 </a:ln>\
1607 </a:lnStyleLst>\
1608 <a:effectStyleLst>\
1609 <a:effectStyle>\
1610 <a:effectLst>\
1611 <a:outerShdw blurRad=\"40000\" dist=\"20000\" dir=\"5400000\" rotWithShape=\"0\">\
1612 <a:srgbClr val=\"000000\">\
1613 <a:alpha val=\"38000\"/>\
1614 </a:srgbClr>\
1615 </a:outerShdw>\
1616 </a:effectLst>\
1617 </a:effectStyle>\
1618 <a:effectStyle>\
1619 <a:effectLst>\
1620 <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">\
1621 <a:srgbClr val=\"000000\">\
1622 <a:alpha val=\"35000\"/>\
1623 </a:srgbClr>\
1624 </a:outerShdw>\
1625 </a:effectLst>\
1626 </a:effectStyle>\
1627 <a:effectStyle>\
1628 <a:effectLst>\
1629 <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">\
1630 <a:srgbClr val=\"000000\">\
1631 <a:alpha val=\"35000\"/>\
1632 </a:srgbClr>\
1633 </a:outerShdw>\
1634 </a:effectLst>\
1635 <a:scene3d>\
1636 <a:camera prst=\"orthographicFront\">\
1637 <a:rot lat=\"0\" lon=\"0\" rev=\"0\"/>\
1638 </a:camera>\
1639 <a:lightRig rig=\"threePt\" dir=\"t\">\
1640 <a:rot lat=\"0\" lon=\"0\" rev=\"1200000\"/>\
1641 </a:lightRig>\
1642 </a:scene3d>\
1643 <a:sp3d>\
1644 <a:bevelT w=\"63500\" h=\"25400\"/>\
1645 </a:sp3d>\
1646 </a:effectStyle>\
1647 </a:effectStyleLst>\
1648 <a:bgFillStyleLst>\
1649 <a:solidFill>\
1650 <a:schemeClr val=\"phClr\"/>\
1651 </a:solidFill>\
1652 <a:gradFill rotWithShape=\"1\">\
1653 <a:gsLst>\
1654 <a:gs pos=\"0\">\
1655 <a:schemeClr val=\"phClr\">\
1656 <a:tint val=\"40000\"/>\
1657 <a:satMod val=\"350000\"/>\
1658 </a:schemeClr>\
1659 </a:gs>\
1660 <a:gs pos=\"40000\">\
1661 <a:schemeClr val=\"phClr\">\
1662 <a:tint val=\"45000\"/>\
1663 <a:shade val=\"99000\"/>\
1664 <a:satMod val=\"350000\"/>\
1665 </a:schemeClr>\
1666 </a:gs>\
1667 <a:gs pos=\"100000\">\
1668 <a:schemeClr val=\"phClr\">\
1669 <a:shade val=\"20000\"/>\
1670 <a:satMod val=\"255000\"/>\
1671 </a:schemeClr>\
1672 </a:gs>\
1673 </a:gsLst>\
1674 <a:path path=\"circle\">\
1675 <a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/>\
1676 </a:path>\
1677 </a:gradFill>\
1678 <a:gradFill rotWithShape=\"1\">\
1679 <a:gsLst>\
1680 <a:gs pos=\"0\">\
1681 <a:schemeClr val=\"phClr\">\
1682 <a:tint val=\"80000\"/>\
1683 <a:satMod val=\"300000\"/>\
1684 </a:schemeClr>\
1685 </a:gs>\
1686 <a:gs pos=\"100000\">\
1687 <a:schemeClr val=\"phClr\">\
1688 <a:shade val=\"30000\"/>\
1689 <a:satMod val=\"200000\"/>\
1690 </a:schemeClr>\
1691 </a:gs>\
1692 </a:gsLst>\
1693 <a:path path=\"circle\">\
1694 <a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/>\
1695 </a:path>\
1696 </a:gradFill>\
1697 </a:bgFillStyleLst>\
1698 </a:fmtScheme>"
1700 void PowerPointExport::WriteDefaultColorSchemes(const FSHelperPtr& pFS)
1702 for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
1704 OUString sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
1705 sal_Int32 nColor = 0;
1707 switch (nId)
1709 case PredefinedClrSchemeId::dk2:
1710 nColor = 0x1F497D;
1711 break;
1712 case PredefinedClrSchemeId::lt2:
1713 nColor = 0xEEECE1;
1714 break;
1715 case PredefinedClrSchemeId::accent1:
1716 nColor = 0x4F81BD;
1717 break;
1718 case PredefinedClrSchemeId::accent2:
1719 nColor = 0xC0504D;
1720 break;
1721 case PredefinedClrSchemeId::accent3:
1722 nColor = 0x9BBB59;
1723 break;
1724 case PredefinedClrSchemeId::accent4:
1725 nColor = 0x8064A2;
1726 break;
1727 case PredefinedClrSchemeId::accent5:
1728 nColor = 0x4BACC6;
1729 break;
1730 case PredefinedClrSchemeId::accent6:
1731 nColor = 0xF79646;
1732 break;
1733 case PredefinedClrSchemeId::hlink:
1734 nColor = 0x0000FF;
1735 break;
1736 case PredefinedClrSchemeId::folHlink:
1737 nColor = 0x800080;
1738 break;
1741 OUString sOpenColorScheme = OUStringBuffer()
1742 .append("<a:")
1743 .append(sName)
1744 .append(">")
1745 .makeStringAndClear();
1746 pFS->write(sOpenColorScheme);
1748 pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(nColor), FSEND);
1750 OUString sCloseColorScheme = OUStringBuffer()
1751 .append("</a:")
1752 .append(sName)
1753 .append(">")
1754 .makeStringAndClear();
1755 pFS->write(sCloseColorScheme);
1759 bool PowerPointExport::WriteColorSchemes(const FSHelperPtr& pFS, const OUString& rThemePath)
1763 uno::Reference<beans::XPropertySet> xDocProps(getModel(), uno::UNO_QUERY);
1764 if (xDocProps.is())
1766 uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
1768 const OUString aGrabBagPropName = "InteropGrabBag";
1769 if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
1771 comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
1772 uno::Sequence<beans::PropertyValue> aCurrentTheme;
1774 aGrabBag.getValue(rThemePath) >>= aCurrentTheme;
1776 if (!aCurrentTheme.getLength())
1777 return false;
1779 // Order is important
1780 for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
1782 OUString sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
1783 sal_Int32 nColor = 0;
1785 for (auto aIt = aCurrentTheme.begin(); aIt != aCurrentTheme.end(); aIt++)
1787 if (aIt->Name == sName)
1789 aIt->Value >>= nColor;
1790 break;
1794 OUString sOpenColorScheme = OUStringBuffer()
1795 .append("<a:")
1796 .append(sName)
1797 .append(">")
1798 .makeStringAndClear();
1799 pFS->write(sOpenColorScheme);
1801 pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(nColor), FSEND);
1803 OUString sCloseColorScheme = OUStringBuffer()
1804 .append("</a:")
1805 .append(sName)
1806 .append(">")
1807 .makeStringAndClear();
1808 pFS->write(sCloseColorScheme);
1811 // TODO: write complete color schemes & only if successful, protection against partial export
1812 return true;
1816 catch (const uno::Exception&)
1818 SAL_WARN("writerfilter", "Failed to save documents grab bag");
1821 return false;
1824 void PowerPointExport::WriteTheme(sal_Int32 nThemeNum)
1826 OUString sThemePath = OUStringBuffer()
1827 .append("ppt/theme/theme")
1828 .append(nThemeNum + 1)
1829 .append(".xml")
1830 .makeStringAndClear();
1832 FSHelperPtr pFS = openFragmentStreamWithSerializer(sThemePath,
1833 "application/vnd.openxmlformats-officedocument.theme+xml");
1835 pFS->startElementNS(XML_a, XML_theme,
1836 FSNS(XML_xmlns, XML_a), OUStringToOString(this->getNamespaceURL(OOX_NS(dml)), RTL_TEXTENCODING_UTF8),
1837 XML_name, "Office Theme",
1838 FSEND);
1840 pFS->startElementNS(XML_a, XML_themeElements, FSEND);
1841 pFS->startElementNS(XML_a, XML_clrScheme, XML_name, "Office", FSEND);
1843 pFS->write(SYS_COLOR_SCHEMES);
1845 if (!WriteColorSchemes(pFS, sThemePath))
1847 // if style is not defined, try to use first one
1848 if (!WriteColorSchemes(pFS, "ppt/theme/theme1.xml"))
1850 // color schemes are required - use default values
1851 WriteDefaultColorSchemes(pFS);
1855 pFS->endElementNS(XML_a, XML_clrScheme);
1857 // export remaining part
1858 pFS->write(MINIMAL_THEME);
1860 pFS->endElementNS(XML_a, XML_themeElements);
1861 pFS->endElementNS(XML_a, XML_theme);
1864 bool PowerPointExport::ImplCreateDocument()
1866 mbCreateNotes = false;
1868 for (sal_uInt32 i = 0; i < mnPages; i++)
1870 if (!GetPageByIndex(i, NOTICE))
1871 return false;
1873 if (ContainsOtherShapeThanPlaceholders())
1875 mbCreateNotes = true;
1876 break;
1880 return true;
1883 void PowerPointExport::WriteNotesMaster()
1885 SAL_INFO("sd.eppt", "write Notes master\n---------------");
1887 mPresentationFS->startElementNS(XML_p, XML_notesMasterIdLst, FSEND);
1889 OUString sRelId = addRelation(mPresentationFS->getOutputStream(),
1890 oox::getRelationship(Relationship::NOTESMASTER),
1891 "notesMasters/notesMaster1.xml");
1893 mPresentationFS->singleElementNS(XML_p, XML_notesMasterId,
1894 FSNS(XML_r, XML_id), USS(sRelId),
1895 FSEND);
1897 mPresentationFS->endElementNS(XML_p, XML_notesMasterIdLst);
1899 FSHelperPtr pFS =
1900 openFragmentStreamWithSerializer("ppt/notesMasters/notesMaster1.xml",
1901 "application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml");
1902 // write theme per master
1903 WriteTheme(mnMasterPages);
1905 // add implicit relation to the presentation theme
1906 addRelation(pFS->getOutputStream(),
1907 oox::getRelationship(Relationship::THEME),
1908 OUStringBuffer()
1909 .append("../theme/theme")
1910 .append(static_cast<sal_Int32>(mnMasterPages) + 1)
1911 .append(".xml")
1912 .makeStringAndClear());
1914 pFS->startElementNS(XML_p, XML_notesMaster, PNMSS, FSEND);
1916 pFS->startElementNS(XML_p, XML_cSld, FSEND);
1918 Reference< XPropertySet > aXBackgroundPropSet;
1919 if (ImplGetPropertyValue(mXPagePropSet, "Background") &&
1920 (mAny >>= aXBackgroundPropSet))
1921 ImplWriteBackground(pFS, aXBackgroundPropSet);
1923 WriteShapeTree(pFS, NOTICE, true);
1925 pFS->endElementNS(XML_p, XML_cSld);
1927 // color map - now it uses colors from hardcoded theme, once we eventually generate theme, this might need update
1928 pFS->singleElementNS(XML_p, XML_clrMap,
1929 XML_bg1, "lt1",
1930 XML_bg2, "lt2",
1931 XML_tx1, "dk1",
1932 XML_tx2, "dk2",
1933 XML_accent1, "accent1",
1934 XML_accent2, "accent2",
1935 XML_accent3, "accent3",
1936 XML_accent4, "accent4",
1937 XML_accent5, "accent5",
1938 XML_accent6, "accent6",
1939 XML_hlink, "hlink",
1940 XML_folHlink, "folHlink",
1941 FSEND);
1943 pFS->endElementNS(XML_p, XML_notesMaster);
1945 SAL_INFO("sd.eppt", "----------------");
1948 sal_Int32 PowerPointExport::GetShapeID(const Reference<XShape>& rXShape)
1950 return ShapeExport::GetShapeID(rXShape, &maShapeMap);
1953 sal_Int32 PowerPointExport::GetNextAnimationNodeID()
1955 return mnAnimationNodeIdMax++;
1958 bool PowerPointExport::ImplCreateMainNotes()
1960 if (mbCreateNotes)
1961 WriteNotesMaster();
1963 return true;
1966 OUString PowerPointExport::getImplementationName()
1968 return OUString("com.sun.star.comp.Impress.oox.PowerPointExport");
1971 // UNO component
1972 extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
1973 css_comp_Impress_oox_PowerPointExport(uno::XComponentContext* rxCtxt,
1974 uno::Sequence<css::uno::Any> const& rArguments)
1976 return cppu::acquire(new PowerPointExport(rxCtxt, rArguments));
1979 #if OSL_DEBUG_LEVEL > 1
1980 void dump_pset(Reference< XPropertySet > const& rXPropSet)
1982 Reference< XPropertySetInfo > info = rXPropSet->getPropertySetInfo();
1983 Sequence< beans::Property > props = info->getProperties();
1985 for (int i=0; i < props.getLength(); i++)
1987 OString name = OUStringToOString(props [i].Name, RTL_TEXTENCODING_UTF8);
1989 Any value = rXPropSet->getPropertyValue(props [i].Name);
1991 OUString strValue;
1992 sal_Int32 intValue;
1993 bool boolValue;
1994 RectanglePoint pointValue;
1996 if (value >>= strValue)
1997 SAL_INFO("sd.eppt", name << " = \"" << strValue << "\"");
1998 else if (value >>= intValue)
1999 SAL_INFO("sd.eppt", name << " = " << intValue << "(hex : " << std::hex << intValue << ")");
2000 else if (value >>= boolValue)
2001 SAL_INFO("sd.eppt", name << " = " << boolValue << " (bool)");
2002 else if (value >>= pointValue)
2003 SAL_INFO("sd.eppt", name << " = " << pointValue << " (RectanglePoint)");
2004 else
2005 SAL_INFO("sd.eppt", "??? <unhandled type>");
2008 #endif
2010 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */