summaryrefslogtreecommitdiffstats
path: root/oox/source/ppt
diff options
context:
space:
mode:
Diffstat (limited to 'oox/source/ppt')
-rw-r--r--oox/source/ppt/animationspersist.cxx220
-rw-r--r--oox/source/ppt/animationtypes.cxx63
-rw-r--r--oox/source/ppt/animationtypes.hxx35
-rw-r--r--oox/source/ppt/animvariantcontext.cxx95
-rw-r--r--oox/source/ppt/animvariantcontext.hxx50
-rw-r--r--oox/source/ppt/backgroundproperties.cxx50
-rw-r--r--oox/source/ppt/buildlistcontext.cxx84
-rw-r--r--oox/source/ppt/buildlistcontext.hxx48
-rw-r--r--oox/source/ppt/comments.cxx89
-rw-r--r--oox/source/ppt/commonbehaviorcontext.cxx145
-rw-r--r--oox/source/ppt/commonbehaviorcontext.hxx65
-rw-r--r--oox/source/ppt/commontimenodecontext.cxx666
-rw-r--r--oox/source/ppt/commontimenodecontext.hxx48
-rw-r--r--oox/source/ppt/conditioncontext.cxx182
-rw-r--r--oox/source/ppt/conditioncontext.hxx67
-rw-r--r--oox/source/ppt/customshowlistcontext.cxx105
-rw-r--r--oox/source/ppt/extdrawingfragmenthandler.cxx64
-rw-r--r--oox/source/ppt/extdrawingfragmenthandler.hxx41
-rw-r--r--oox/source/ppt/headerfootercontext.cxx58
-rw-r--r--oox/source/ppt/headerfootercontext.hxx42
-rw-r--r--oox/source/ppt/layoutfragmenthandler.cxx72
-rw-r--r--oox/source/ppt/pptfilterhelpers.cxx422
-rw-r--r--oox/source/ppt/pptgraphicshapecontext.cxx189
-rw-r--r--oox/source/ppt/pptimport.cxx309
-rw-r--r--oox/source/ppt/pptshape.cxx809
-rw-r--r--oox/source/ppt/pptshapecontext.cxx195
-rw-r--r--oox/source/ppt/pptshapegroupcontext.cxx158
-rw-r--r--oox/source/ppt/pptshapepropertiescontext.cxx56
-rw-r--r--oox/source/ppt/presPropsfragmenthandler.cxx89
-rw-r--r--oox/source/ppt/presentationfragmenthandler.cxx792
-rw-r--r--oox/source/ppt/slidefragmenthandler.cxx265
-rw-r--r--oox/source/ppt/slidemastertextstylescontext.cxx79
-rw-r--r--oox/source/ppt/slidepersist.cxx555
-rw-r--r--oox/source/ppt/slidetimingcontext.cxx70
-rw-r--r--oox/source/ppt/slidetransition.cxx467
-rw-r--r--oox/source/ppt/slidetransitioncontext.cxx200
-rw-r--r--oox/source/ppt/soundactioncontext.cxx109
-rw-r--r--oox/source/ppt/timeanimvaluecontext.cxx84
-rw-r--r--oox/source/ppt/timeanimvaluecontext.hxx51
-rw-r--r--oox/source/ppt/timenode.cxx668
-rw-r--r--oox/source/ppt/timenodelistcontext.cxx1048
-rw-r--r--oox/source/ppt/timetargetelementcontext.cxx168
-rw-r--r--oox/source/ppt/timetargetelementcontext.hxx45
43 files changed, 9117 insertions, 0 deletions
diff --git a/oox/source/ppt/animationspersist.cxx b/oox/source/ppt/animationspersist.cxx
new file mode 100644
index 000000000..450e3da00
--- /dev/null
+++ b/oox/source/ppt/animationspersist.cxx
@@ -0,0 +1,220 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/animationspersist.hxx>
+
+#include <rtl/ustring.hxx>
+#include <sal/log.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/presentation/ParagraphTarget.hpp>
+#include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
+#include <com/sun/star/animations/Event.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+
+#include <oox/drawingml/shape.hxx>
+#include <oox/helper/addtosequence.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::text;
+
+namespace oox
+{
+
+Any addToSequence( const Any& rOldValue, const Any& rNewValue )
+{
+ if( !rNewValue.hasValue() )
+ {
+ return rOldValue;
+ }
+ else if( !rOldValue.hasValue() )
+ {
+ return rNewValue;
+ }
+ else
+ {
+ Sequence< Any > aNewSeq;
+ if( rOldValue >>= aNewSeq )
+ {
+ sal_Int32 nSize = aNewSeq.getLength();
+ aNewSeq.realloc(nSize+1);
+ aNewSeq.getArray()[nSize] = rNewValue;
+ }
+ else
+ {
+ aNewSeq = { rOldValue, rNewValue };
+ }
+ return Any( aNewSeq );
+ }
+}
+
+} // namespace oox
+
+namespace oox::ppt {
+
+ void ShapeTargetElement::convert( css::uno::Any & rTarget, sal_Int16 & rSubType ) const
+ {
+ switch(mnType)
+ {
+ case XML_subSp:
+ rSubType = ShapeAnimationSubType::AS_WHOLE;
+ break;
+ case XML_bg:
+ rSubType = ShapeAnimationSubType::ONLY_BACKGROUND;
+ break;
+ case XML_txEl:
+ {
+ ParagraphTarget aParaTarget;
+ Reference< XShape > xShape;
+ rTarget >>= xShape;
+ aParaTarget.Shape = xShape;
+ rSubType = ShapeAnimationSubType::ONLY_TEXT;
+
+ Reference< XText > xText( xShape, UNO_QUERY );
+ if( xText.is() )
+ {
+ switch(mnRangeType)
+ {
+ case XML_charRg:
+ // TODO calculate the corresponding paragraph for the text range...
+ SAL_INFO("oox.ppt", "OOX: TODO calculate the corresponding paragraph for the text range..." );
+ break;
+ case XML_pRg:
+ aParaTarget.Paragraph = static_cast< sal_Int16 >( maRange.start );
+ // TODO what to do with more than one.
+ SAL_INFO("oox.ppt", "OOX: TODO what to do with more than one" );
+ break;
+ }
+ rTarget <<= aParaTarget;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ Any AnimTargetElement::convert(const SlidePersistPtr & pSlide, sal_Int16 & nSubType) const
+ {
+ Any aTarget;
+ // see sd/source/files/ppt/pptinanimations.cxx:3191 (in importTargetElementContainer())
+ switch(mnType)
+ {
+ case XML_inkTgt:
+ // TODO
+ SAL_INFO("oox.ppt", "OOX: TODO inkTgt" );
+ break;
+ case XML_sldTgt:
+ // TODO
+ SAL_INFO("oox.ppt", "OOX: TODO sldTgt" );
+ break;
+ case XML_sndTgt:
+ aTarget <<= msValue;
+ break;
+ case XML_spTgt:
+ {
+ OUString sShapeName = msValue;
+
+ // bnc#705982 - catch referenced diagram fallback shapes
+ if( maShapeTarget.mnType == XML_dgm )
+ sShapeName = maShapeTarget.msSubShapeId;
+
+ Any rTarget;
+ ::oox::drawingml::ShapePtr pShape = pSlide->getShape( sShapeName );
+ SAL_WARN_IF( !pShape, "oox.ppt", "failed to locate Shape" );
+
+ if( !pShape && maShapeTarget.mnType == XML_dgm )
+ {
+ pShape = pSlide->getShape( msValue );
+ }
+
+ if( pShape )
+ {
+ Reference< XShape > xShape( pShape->getXShape() );
+ SAL_WARN_IF( !xShape.is(), "oox.ppt", "fail to get XShape from shape" );
+ if( xShape.is() )
+ {
+ rTarget <<= xShape;
+ maShapeTarget.convert(rTarget, nSubType);
+ aTarget = rTarget;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return aTarget;
+ }
+
+ // Convert a time node condition to XAnimation.Begin or XAnimation.End
+ Any AnimationCondition::convert(const SlidePersistPtr & pSlide) const
+ {
+ Any aAny;
+ Event aEvent;
+ if(mpTarget && (maValue >>= aEvent))
+ {
+ sal_Int16 nSubType;
+ aAny = mpTarget->convert( pSlide, nSubType );
+ aEvent.Source = aAny;
+ aAny <<= aEvent;
+ }
+ else if (mnType == PPT_TOKEN(tn) && (maValue >>= aEvent))
+ {
+ OUString sId;
+ aEvent.Source >>= sId;
+ css::uno::Reference<XAnimationNode> xNode = pSlide->getAnimationNode(sId);
+ if (xNode.is())
+ {
+ aEvent.Source <<= xNode;
+ }
+ else
+ aEvent.Source.clear();
+ aAny <<= aEvent;
+ }
+ else
+ {
+ aAny = maValue;
+ }
+ return aAny;
+ }
+
+ Any AnimationCondition::convertList(const SlidePersistPtr & pSlide, const AnimationConditionList & l)
+ {
+ Any aAny;
+
+ if (l.size() == 1)
+ return l[0].convert(pSlide);
+
+ for (auto const& elem : l)
+ {
+ aAny = addToSequence( aAny, elem.convert(pSlide) );
+ }
+ return aAny;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/animationtypes.cxx b/oox/source/ppt/animationtypes.cxx
new file mode 100644
index 000000000..c6b49b3e8
--- /dev/null
+++ b/oox/source/ppt/animationtypes.cxx
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "animationtypes.hxx"
+
+#include <com/sun/star/animations/Timing.hpp>
+
+#include <oox/helper/attributelist.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt
+{
+// ST_TLTime
+Any GetTime(const OUString& val)
+{
+ Any aDuration;
+ if (val == "indefinite")
+ {
+ aDuration <<= Timing_INDEFINITE;
+ }
+ else
+ {
+ aDuration <<= val.toFloat() / 1000.0;
+ }
+ return aDuration;
+}
+
+// ST_TLTimeAnimateValueTime
+Any GetTimeAnimateValueTime(const OUString& val)
+{
+ Any aPercent;
+ if (val == "indefinite")
+ {
+ aPercent <<= Timing_INDEFINITE;
+ }
+ else
+ {
+ aPercent <<= val.toFloat() / 100000.0;
+ }
+ return aPercent;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/animationtypes.hxx b/oox/source/ppt/animationtypes.hxx
new file mode 100644
index 000000000..92652978f
--- /dev/null
+++ b/oox/source/ppt/animationtypes.hxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_ANIMATIONTYPES_HXX
+#define INCLUDED_OOX_SOURCE_PPT_ANIMATIONTYPES_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+
+namespace oox::ppt
+{
+// ST_TLTime
+css::uno::Any GetTime(const OUString& val);
+// ST_TLTimeAnimateValueTime
+css::uno::Any GetTimeAnimateValueTime(const OUString& val);
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/animvariantcontext.cxx b/oox/source/ppt/animvariantcontext.cxx
new file mode 100644
index 000000000..5f2faf799
--- /dev/null
+++ b/oox/source/ppt/animvariantcontext.cxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "animvariantcontext.hxx"
+
+#include <com/sun/star/uno/Any.hxx>
+#include <rtl/ustring.hxx>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <drawingml/colorchoicecontext.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+ AnimVariantContext::AnimVariantContext( FragmentHandler2 const & rParent, sal_Int32 aElement, Any & aValue )
+ : FragmentHandler2( rParent )
+ , mnElement( aElement )
+ , maValue( aValue )
+ {
+ }
+
+ AnimVariantContext::~AnimVariantContext( ) noexcept
+ {
+ }
+
+ void AnimVariantContext::onEndElement()
+ {
+ if( isCurrentElement( mnElement ) && maColor.isUsed() )
+ {
+ maValue <<= maColor.getColor( getFilter().getGraphicHelper() );
+ }
+ }
+
+ ContextHandlerRef AnimVariantContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( boolVal ):
+ {
+ bool val = rAttribs.getBool( XML_val, false );
+ maValue <<= val;
+ return this;
+ }
+ case PPT_TOKEN( clrVal ):
+ return new ::oox::drawingml::ColorContext( *this, maColor );
+ // we'll defer setting the Any until the end.
+ case PPT_TOKEN( fltVal ):
+ {
+ double val = rAttribs.getDouble( XML_val, 0.0 );
+ maValue <<= val;
+ return this;
+ }
+ case PPT_TOKEN( intVal ):
+ {
+ sal_Int32 val = rAttribs.getInteger( XML_val, 0 );
+ maValue <<= val;
+ return this;
+ }
+ case PPT_TOKEN( strVal ):
+ {
+ OUString val = rAttribs.getString( XML_val, OUString() );
+ maValue <<= val;
+ return this;
+ }
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/animvariantcontext.hxx b/oox/source/ppt/animvariantcontext.hxx
new file mode 100644
index 000000000..8830e0e6a
--- /dev/null
+++ b/oox/source/ppt/animvariantcontext.hxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_ANIMVARIANTCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_ANIMVARIANTCONTEXT_HXX
+
+#include <com/sun/star/uno/Any.hxx>
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/drawingml/color.hxx>
+
+namespace oox::ppt {
+
+ /** context CT_TLAnimVariant */
+ class AnimVariantContext
+ : public ::oox::core::FragmentHandler2
+ {
+ public:
+ AnimVariantContext( ::oox::core::FragmentHandler2 const & rParent, ::sal_Int32 aElement, css::uno::Any & aValue );
+ virtual ~AnimVariantContext( ) noexcept override;
+ virtual void onEndElement() override;
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ ::sal_Int32 mnElement;
+ css::uno::Any& maValue;
+ ::oox::drawingml::Color maColor;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/backgroundproperties.cxx b/oox/source/ppt/backgroundproperties.cxx
new file mode 100644
index 000000000..9fe256612
--- /dev/null
+++ b/oox/source/ppt/backgroundproperties.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/backgroundproperties.hxx>
+#include <drawingml/misccontexts.hxx>
+#include <oox/core/contexthandler2.hxx>
+#include <oox/token/namespaces.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+BackgroundPropertiesContext::BackgroundPropertiesContext( FragmentHandler2 const & rParent, ::oox::drawingml::FillProperties& rFillProperties )
+: FragmentHandler2( rParent )
+, mrFillProperties( rFillProperties )
+{
+}
+
+::oox::core::ContextHandlerRef BackgroundPropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( fill ): // a:CT_FillEffect
+ return this;
+ }
+
+ return ::oox::drawingml::FillPropertiesContext::createFillContext( *this, aElementToken, rAttribs, mrFillProperties );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/buildlistcontext.cxx b/oox/source/ppt/buildlistcontext.cxx
new file mode 100644
index 000000000..011d30346
--- /dev/null
+++ b/oox/source/ppt/buildlistcontext.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "buildlistcontext.hxx"
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+
+namespace oox::ppt {
+
+ BuildListContext::BuildListContext( FragmentHandler2 const & rParent )
+ : FragmentHandler2( rParent )
+ , mbInBldGraphic( false )
+ , mbBuildAsOne( false )
+ {
+ }
+
+ BuildListContext::~BuildListContext( )
+ {
+ }
+
+ void BuildListContext::onEndElement()
+ {
+ switch( getCurrentElement() )
+ {
+ case PPT_TOKEN( bldGraphic ):
+ mbInBldGraphic = false;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ::oox::core::ContextHandlerRef BuildListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ )
+ {
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( bldAsOne ):
+ if( mbInBldGraphic )
+ {
+ mbBuildAsOne = true;
+ }
+ return this;
+ case PPT_TOKEN( bldSub ):
+ return this;
+ case PPT_TOKEN( bldGraphic ):
+ {
+ mbInBldGraphic = true;
+// OUString sShapeId = rAttribs.getString( XML_spid, OUString() );
+// TODO
+// bool uiExpand = rAttribs.getBool( XML_uiExpand, true );
+ /* this is unsigned */
+// sal_uInt32 nGroupId = rAttribs.getUnsignedInteger( XML_grpId, 0 );
+ return this;
+ }
+ case A_TOKEN( bldDgm ):
+ case A_TOKEN( bldOleChart ):
+ case A_TOKEN( bldP ):
+ return this;
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/buildlistcontext.hxx b/oox/source/ppt/buildlistcontext.hxx
new file mode 100644
index 000000000..a95e464e9
--- /dev/null
+++ b/oox/source/ppt/buildlistcontext.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_BUILDLISTCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_BUILDLISTCONTEXT_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+
+namespace oox::ppt {
+
+ /** CT_BuildList */
+ class BuildListContext
+ : public ::oox::core::FragmentHandler2
+ {
+ public:
+ explicit BuildListContext( ::oox::core::FragmentHandler2 const & rParent );
+
+ virtual ~BuildListContext( ) override;
+
+ virtual void onEndElement() override;
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+ private:
+ bool mbInBldGraphic;
+ bool mbBuildAsOne;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/comments.cxx b/oox/source/ppt/comments.cxx
new file mode 100644
index 000000000..c38397fca
--- /dev/null
+++ b/oox/source/ppt/comments.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <oox/ppt/comments.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <rtl/math.h>
+#include <rtl/math.hxx>
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace oox::ppt
+{
+void CommentAuthorList::setValues(const CommentAuthorList& list)
+{
+ for (auto const& author : list.cmAuthorLst)
+ {
+ CommentAuthor temp;
+ // TODO JNA : why not doing push_back at the end instead of using back()?
+ cmAuthorLst.push_back(temp);
+ cmAuthorLst.back().clrIdx = author.clrIdx;
+ cmAuthorLst.back().id = author.id;
+ cmAuthorLst.back().initials = author.initials;
+ cmAuthorLst.back().lastIdx = author.lastIdx;
+ cmAuthorLst.back().name = author.name;
+ }
+}
+
+//DateTime is saved as : 2013-01-10T15:53:26.000
+void Comment::setDateTime(const OUString& sDateTime)
+{
+ sal_Int32 nIdx{ 0 };
+ aDateTime.Year = o3tl::toInt32(o3tl::getToken(sDateTime, 0, '-', nIdx));
+ aDateTime.Month = o3tl::toUInt32(o3tl::getToken(sDateTime, 0, '-', nIdx));
+ aDateTime.Day = o3tl::toUInt32(o3tl::getToken(sDateTime, 0, 'T', nIdx));
+ aDateTime.Hours = o3tl::toUInt32(o3tl::getToken(sDateTime, 0, ':', nIdx));
+ aDateTime.Minutes = o3tl::toUInt32(o3tl::getToken(sDateTime, 0, ':', nIdx));
+ double seconds = rtl_math_uStringToDouble(sDateTime.getStr() + nIdx,
+ sDateTime.getStr() + sDateTime.getLength(), '.', 0,
+ nullptr, nullptr);
+ aDateTime.Seconds = floor(seconds);
+ seconds -= aDateTime.Seconds;
+ aDateTime.NanoSeconds = ::rtl::math::round(seconds * 1000000000);
+ const int secondsOverflow = (aDateTime.Seconds == 60) ? 61 : 60;
+ // normalise time part of aDateTime
+ if (aDateTime.NanoSeconds == 1000000000)
+ {
+ aDateTime.NanoSeconds = 0;
+ ++aDateTime.Seconds;
+ }
+ if (aDateTime.Seconds == secondsOverflow)
+ {
+ aDateTime.Seconds = 0;
+ ++aDateTime.Minutes;
+ }
+ if (aDateTime.Minutes == 60)
+ {
+ aDateTime.Minutes = 0;
+ ++aDateTime.Hours;
+ }
+ // if overflow goes into date, I give up
+}
+
+OUString Comment::getAuthor(const CommentAuthorList& list)
+{
+ const sal_Int32 nId = authorId.toInt32();
+ for (auto const& author : list.cmAuthorLst)
+ {
+ if (author.id.toInt32() == nId)
+ return author.name;
+ }
+ return "Anonymous";
+}
+
+const Comment& CommentList::getCommentAtIndex(int index)
+{
+ if (index < 0 || o3tl::make_unsigned(index) >= cmLst.size())
+ throw css::lang::IllegalArgumentException();
+
+ return cmLst.at(index);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/commonbehaviorcontext.cxx b/oox/source/ppt/commonbehaviorcontext.cxx
new file mode 100644
index 000000000..4ba40925a
--- /dev/null
+++ b/oox/source/ppt/commonbehaviorcontext.cxx
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/ppt/pptfilterhelpers.hxx>
+
+#include "commonbehaviorcontext.hxx"
+#include "commontimenodecontext.hxx"
+#include "timetargetelementcontext.hxx"
+
+#include <string.h>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+ CommonBehaviorContext::CommonBehaviorContext( FragmentHandler2 const & rParent,
+ const TimeNodePtr & pNode)
+ : FragmentHandler2(rParent)
+ , mbInAttrList( false )
+ , mbIsInAttrName( false )
+ , mpNode(pNode)
+ {
+ }
+
+ CommonBehaviorContext::~CommonBehaviorContext( ) noexcept
+ {
+ }
+
+ void CommonBehaviorContext::onEndElement()
+ {
+ switch( getCurrentElement() )
+ {
+ case PPT_TOKEN( cBhvr ):
+ {
+ if( !maAttributes.empty() )
+ {
+ OUStringBuffer sAttributes;
+ for (auto const& attribute : maAttributes)
+ {
+ if( !sAttributes.isEmpty() )
+ {
+ sAttributes.append( ";" );
+ }
+ sAttributes.append( attribute.name );
+ }
+ OUString sTmp( sAttributes.makeStringAndClear() );
+ mpNode->getNodeProperties()[ NP_ATTRIBUTENAME ] <<= sTmp;
+ }
+ break;
+ }
+ case PPT_TOKEN( attrNameLst ):
+ mbInAttrList = false;
+ break;
+ case PPT_TOKEN( attrName ):
+ if( mbIsInAttrName )
+ {
+ const ImplAttributeNameConversion *attrConv = getAttributeConversionList();
+ while( attrConv->mpMSName != nullptr )
+ {
+ if(msCurrentAttribute.equalsAscii( attrConv->mpMSName ) )
+ {
+ Attribute attr;
+ attr.name = OUString::intern( attrConv->mpAPIName,
+ strlen(attrConv->mpAPIName),
+ RTL_TEXTENCODING_ASCII_US );
+ attr.type = attrConv->meAttribute;
+ maAttributes.push_back( attr );
+ SAL_INFO("oox.ppt", "OOX: attrName is " << msCurrentAttribute << " -> " << attrConv->mpAPIName );
+ break;
+ }
+ attrConv++;
+ }
+ mbIsInAttrName = false;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ void CommonBehaviorContext::onCharacters( const OUString& aChars )
+ {
+ if( mbIsInAttrName )
+ {
+ msCurrentAttribute += aChars;
+ }
+ }
+
+ ::oox::core::ContextHandlerRef CommonBehaviorContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cTn ):
+ return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
+ case PPT_TOKEN( tgtEl ):
+ return new TimeTargetElementContext( *this, mpNode->getTarget() );
+ case PPT_TOKEN( attrNameLst ):
+ mbInAttrList = true;
+ return this;
+ case PPT_TOKEN( attrName ):
+ {
+ if( mbInAttrList )
+ {
+ mbIsInAttrName = true;
+ msCurrentAttribute.clear();
+ }
+ else
+ {
+ SAL_INFO("oox.ppt", "OOX: Attribute Name outside an Attribute List" );
+ }
+ return this;
+ }
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/commonbehaviorcontext.hxx b/oox/source/ppt/commonbehaviorcontext.hxx
new file mode 100644
index 000000000..eb6bc28fc
--- /dev/null
+++ b/oox/source/ppt/commonbehaviorcontext.hxx
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_COMMONBEHAVIORCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_COMMONBEHAVIORCONTEXT_HXX
+
+#include <rtl/ustring.hxx>
+#include <oox/core/contexthandler.hxx>
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/ppt/pptfilterhelpers.hxx>
+#include <oox/ppt/timenode.hxx>
+
+namespace oox::ppt {
+
+ struct Attribute
+ {
+ OUString name;
+ AnimationAttributeEnum type;
+ };
+
+ /** CT_TLCommonBehaviorData */
+ class CommonBehaviorContext
+ : public ::oox::core::FragmentHandler2
+ {
+ public:
+ CommonBehaviorContext( ::oox::core::FragmentHandler2 const & rParent,
+ const TimeNodePtr & pNode );
+ virtual ~CommonBehaviorContext( )
+ noexcept override;
+
+ virtual void onEndElement() override;
+
+ virtual void onCharacters( const OUString& aChars ) override;
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ bool mbInAttrList;
+ bool mbIsInAttrName;
+ std::vector< Attribute > maAttributes;
+ OUString msCurrentAttribute;
+ const TimeNodePtr& mpNode;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/commontimenodecontext.cxx b/oox/source/ppt/commontimenodecontext.cxx
new file mode 100644
index 000000000..e7d1cf1dc
--- /dev/null
+++ b/oox/source/ppt/commontimenodecontext.cxx
@@ -0,0 +1,666 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "commontimenodecontext.hxx"
+#include "conditioncontext.hxx"
+
+#include <com/sun/star/animations/AnimationFill.hpp>
+#include <com/sun/star/animations/AnimationRestart.hpp>
+#include <com/sun/star/presentation/TextAnimationType.hpp>
+#include <com/sun/star/presentation/EffectPresetClass.hpp>
+#include <com/sun/star/presentation/EffectNodeType.hpp>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/ppt/pptfilterhelpers.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+#include "animationtypes.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::xml::sax;
+
+
+namespace oox::ppt {
+
+const convert_subtype* convert_subtype::getList()
+{
+ static const convert_subtype aList[] =
+ {
+ // fly in
+ { 1, "from-top" },
+ { 2, "from-right" },
+ { 3, "from-top-right" },
+ { 4, "from-bottom" },
+ { 5, "horizontal" },
+ { 6, "from-bottom-right" },
+ { 8, "from-left" },
+ { 9, "from-top-left" },
+ { 10, "vertical" },
+ { 12, "from-bottom-left" },
+ { 16, "in" },
+ { 21, "vertical-in" },
+ { 26, "horizontal-in" },
+ { 32, "out" },
+ { 36, "out-from-screen-center" },
+ { 37, "vertical-out" },
+ { 42, "horizontal-out" },
+ { 272, "in-slightly" },
+ { 288, "out-slightly" },
+ { 528, "in-from-screen-center" },
+ { 0, nullptr }
+ };
+
+ return aList;
+}
+
+const preset_mapping* preset_mapping::getList()
+{
+
+ static const preset_mapping aList[] =
+ {
+ { css::presentation::EffectPresetClass::ENTRANCE, 1 ,"ooo-entrance-appear" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 2 ,"ooo-entrance-fly-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 3 ,"ooo-entrance-venetian-blinds" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 4 ,"ooo-entrance-box" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 5 ,"ooo-entrance-checkerboard" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 6 ,"ooo-entrance-circle" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 7 ,"ooo-entrance-fly-in-slow" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 8 ,"ooo-entrance-diamond" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 9 ,"ooo-entrance-dissolve-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 10 ,"ooo-entrance-fade-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 11 ,"ooo-entrance-flash-once" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 12 ,"ooo-entrance-peek-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 13 ,"ooo-entrance-plus" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 14 ,"ooo-entrance-random-bars" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 15 ,"ooo-entrance-spiral-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 16 ,"ooo-entrance-split" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 17 ,"ooo-entrance-stretchy" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 18 ,"ooo-entrance-diagonal-squares" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 19 ,"ooo-entrance-swivel" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 20 ,"ooo-entrance-wedge" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 21 ,"ooo-entrance-wheel" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 22 ,"ooo-entrance-wipe" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 23 ,"ooo-entrance-zoom" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 24 ,"ooo-entrance-random" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 25 ,"ooo-entrance-boomerang" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 26 ,"ooo-entrance-bounce" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 27 ,"ooo-entrance-colored-lettering" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 28 ,"ooo-entrance-movie-credits" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 29 ,"ooo-entrance-ease-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 30 ,"ooo-entrance-float" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 31 ,"ooo-entrance-turn-and-grow" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 34 ,"ooo-entrance-breaks" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 35 ,"ooo-entrance-pinwheel" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 37 ,"ooo-entrance-rise-up" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 38 ,"ooo-entrance-falling-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 39 ,"ooo-entrance-thread" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 40 ,"ooo-entrance-unfold" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 41 ,"ooo-entrance-whip" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 42 ,"ooo-entrance-ascend" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 43 ,"ooo-entrance-center-revolve" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 45 ,"ooo-entrance-fade-in-and-swivel" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 47 ,"ooo-entrance-descend" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 48 ,"ooo-entrance-sling" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 49 ,"ooo-entrance-spin-in" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 50 ,"ooo-entrance-compress" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 51 ,"ooo-entrance-magnify" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 52 ,"ooo-entrance-curve-up" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 53 ,"ooo-entrance-fade-in-and-zoom" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 54 ,"ooo-entrance-glide" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 55 ,"ooo-entrance-expand" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 56 ,"ooo-entrance-flip" },
+ { css::presentation::EffectPresetClass::ENTRANCE, 58 ,"ooo-entrance-fold" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 1 ,"ooo-emphasis-fill-color" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 2 ,"ooo-emphasis-font" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 3 ,"ooo-emphasis-font-color" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 4 ,"ooo-emphasis-font-size" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 5 ,"ooo-emphasis-font-style" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 6 ,"ooo-emphasis-grow-and-shrink" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 7 ,"ooo-emphasis-line-color" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 8 ,"ooo-emphasis-spin" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 9 ,"ooo-emphasis-transparency" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 10 ,"ooo-emphasis-bold-flash" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 14 ,"ooo-emphasis-blast" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 15 ,"ooo-emphasis-bold-reveal" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 16 ,"ooo-emphasis-color-over-by-word" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 18 ,"ooo-emphasis-reveal-underline" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 19 ,"ooo-emphasis-color-blend" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 20 ,"ooo-emphasis-color-over-by-letter" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 21 ,"ooo-emphasis-complementary-color" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 22 ,"ooo-emphasis-complementary-color-2" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 23 ,"ooo-emphasis-contrasting-color" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 24 ,"ooo-emphasis-darken" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 25 ,"ooo-emphasis-desaturate" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 26 ,"ooo-emphasis-flash-bulb" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 27 ,"ooo-emphasis-flicker" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 28 ,"ooo-emphasis-grow-with-color" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 30 ,"ooo-emphasis-lighten" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 31 ,"ooo-emphasis-style-emphasis" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 32 ,"ooo-emphasis-teeter" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 33 ,"ooo-emphasis-vertical-highlight" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 34 ,"ooo-emphasis-wave" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 35 ,"ooo-emphasis-blink" },
+ { css::presentation::EffectPresetClass::EMPHASIS, 36 ,"ooo-emphasis-shimmer" },
+ { css::presentation::EffectPresetClass::EXIT, 1 ,"ooo-exit-disappear" },
+ { css::presentation::EffectPresetClass::EXIT, 2 ,"ooo-exit-fly-out" },
+ { css::presentation::EffectPresetClass::EXIT, 3 ,"ooo-exit-venetian-blinds" },
+ { css::presentation::EffectPresetClass::EXIT, 4 ,"ooo-exit-box" },
+ { css::presentation::EffectPresetClass::EXIT, 5 ,"ooo-exit-checkerboard" },
+ { css::presentation::EffectPresetClass::EXIT, 6 ,"ooo-exit-circle" },
+ { css::presentation::EffectPresetClass::EXIT, 7 ,"ooo-exit-crawl-out" },
+ { css::presentation::EffectPresetClass::EXIT, 8 ,"ooo-exit-diamond" },
+ { css::presentation::EffectPresetClass::EXIT, 9 ,"ooo-exit-dissolve" },
+ { css::presentation::EffectPresetClass::EXIT, 10 ,"ooo-exit-fade-out" },
+ { css::presentation::EffectPresetClass::EXIT, 11 ,"ooo-exit-flash-once" },
+ { css::presentation::EffectPresetClass::EXIT, 12 ,"ooo-exit-peek-out" },
+ { css::presentation::EffectPresetClass::EXIT, 13 ,"ooo-exit-plus" },
+ { css::presentation::EffectPresetClass::EXIT, 14 ,"ooo-exit-random-bars" },
+ { css::presentation::EffectPresetClass::EXIT, 15 ,"ooo-exit-spiral-out" },
+ { css::presentation::EffectPresetClass::EXIT, 16 ,"ooo-exit-split" },
+ { css::presentation::EffectPresetClass::EXIT, 17 ,"ooo-exit-collapse" },
+ { css::presentation::EffectPresetClass::EXIT, 18 ,"ooo-exit-diagonal-squares" },
+ { css::presentation::EffectPresetClass::EXIT, 19 ,"ooo-exit-swivel" },
+ { css::presentation::EffectPresetClass::EXIT, 20 ,"ooo-exit-wedge" },
+ { css::presentation::EffectPresetClass::EXIT, 21 ,"ooo-exit-wheel" },
+ { css::presentation::EffectPresetClass::EXIT, 22 ,"ooo-exit-wipe" },
+ { css::presentation::EffectPresetClass::EXIT, 23 ,"ooo-exit-zoom" },
+ { css::presentation::EffectPresetClass::EXIT, 24 ,"ooo-exit-random" },
+ { css::presentation::EffectPresetClass::EXIT, 25 ,"ooo-exit-boomerang" },
+ { css::presentation::EffectPresetClass::EXIT, 26 ,"ooo-exit-bounce" },
+ { css::presentation::EffectPresetClass::EXIT, 27 ,"ooo-exit-colored-lettering" },
+ { css::presentation::EffectPresetClass::EXIT, 28 ,"ooo-exit-movie-credits" },
+ { css::presentation::EffectPresetClass::EXIT, 29 ,"ooo-exit-ease-out" },
+ { css::presentation::EffectPresetClass::EXIT, 30 ,"ooo-exit-float" },
+ { css::presentation::EffectPresetClass::EXIT, 31 ,"ooo-exit-turn-and-grow" },
+ { css::presentation::EffectPresetClass::EXIT, 34 ,"ooo-exit-breaks" },
+ { css::presentation::EffectPresetClass::EXIT, 35 ,"ooo-exit-pinwheel" },
+ { css::presentation::EffectPresetClass::EXIT, 37 ,"ooo-exit-sink-down" },
+ { css::presentation::EffectPresetClass::EXIT, 38 ,"ooo-exit-swish" },
+ { css::presentation::EffectPresetClass::EXIT, 39 ,"ooo-exit-thread" },
+ { css::presentation::EffectPresetClass::EXIT, 40 ,"ooo-exit-unfold" },
+ { css::presentation::EffectPresetClass::EXIT, 41 ,"ooo-exit-whip" },
+ { css::presentation::EffectPresetClass::EXIT, 42 ,"ooo-exit-descend" },
+ { css::presentation::EffectPresetClass::EXIT, 43 ,"ooo-exit-center-revolve" },
+ { css::presentation::EffectPresetClass::EXIT, 45 ,"ooo-exit-fade-out-and-swivel" },
+ { css::presentation::EffectPresetClass::EXIT, 47 ,"ooo-exit-ascend" },
+ { css::presentation::EffectPresetClass::EXIT, 48 ,"ooo-exit-sling" },
+ { css::presentation::EffectPresetClass::EXIT, 53 ,"ooo-exit-fade-out-and-zoom" },
+ { css::presentation::EffectPresetClass::EXIT, 55 ,"ooo-exit-contract" },
+ { css::presentation::EffectPresetClass::EXIT, 49 ,"ooo-exit-spin-out" },
+ { css::presentation::EffectPresetClass::EXIT, 50 ,"ooo-exit-stretchy" },
+ { css::presentation::EffectPresetClass::EXIT, 51 ,"ooo-exit-magnify" },
+ { css::presentation::EffectPresetClass::EXIT, 52 ,"ooo-exit-curve-down" },
+ { css::presentation::EffectPresetClass::EXIT, 54 ,"ooo-exit-glide" },
+ { css::presentation::EffectPresetClass::EXIT, 56 ,"ooo-exit-flip" },
+ { css::presentation::EffectPresetClass::EXIT, 58 ,"ooo-exit-fold" },
+
+ { css::presentation::EffectPresetClass::MOTIONPATH, 16 ,"ooo-motionpath-4-point-star" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 5 ,"ooo-motionpath-5-point-star" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 11 ,"ooo-motionpath-6-point-star" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 17 ,"ooo-motionpath-8-point-star" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 1 ,"ooo-motionpath-circle" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 6 ,"ooo-motionpath-crescent-moon" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 3 ,"ooo-motionpath-diamond" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 13 ,"ooo-motionpath-equal-triangle" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 12 ,"ooo-motionpath-oval" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 9 ,"ooo-motionpath-heart" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 4 ,"ooo-motionpath-hexagon" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 10 ,"ooo-motionpath-octagon" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 14 ,"ooo-motionpath-parallelogram" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 15 ,"ooo-motionpath-pentagon" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 2 ,"ooo-motionpath-right-triangle" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 7 ,"ooo-motionpath-square" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 18 ,"ooo-motionpath-teardrop" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 8 ,"ooo-motionpath-trapezoid" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 37 ,"ooo-motionpath-arc-down" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 51 ,"ooo-motionpath-arc-left" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 58 ,"ooo-motionpath-arc-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 44 ,"ooo-motionpath-arc-up" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 41 ,"ooo-motionpath-bounce-left" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 54 ,"ooo-motionpath-bounce-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 48 ,"ooo-motionpath-curvy-left" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 61 ,"ooo-motionpath-curvy-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 60 ,"ooo-motionpath-decaying-wave" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 49 ,"ooo-motionpath-diagonal-down-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 56 ,"ooo-motionpath-diagonal-up-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 42 ,"ooo-motionpath-down" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 52 ,"ooo-motionpath-funnel" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 53 ,"ooo-motionpath-spring" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 62 ,"ooo-motionpath-stairs-down" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 50 ,"ooo-motionpath-turn-down" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 36 ,"ooo-motionpath-turn-down-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 43 ,"ooo-motionpath-turn-up" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 57 ,"ooo-motionpath-turn-up-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 64 ,"ooo-motionpath-up" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 47 ,"ooo-motionpath-wave" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 38 ,"ooo-motionpath-zigzag" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 31 ,"ooo-motionpath-bean" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 25 ,"ooo-motionpath-buzz-saw" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 20 ,"ooo-motionpath-curved-square" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 21 ,"ooo-motionpath-curved-x" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 23 ,"ooo-motionpath-curvy-star" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 28 ,"ooo-motionpath-figure-8-four" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 26 ,"ooo-motionpath-horizontal-figure-8" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 34 ,"ooo-motionpath-inverted-square" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 33 ,"ooo-motionpath-inverted-triangle" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 24 ,"ooo-motionpath-loop-de-loop" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 29 ,"ooo-motionpath-neutron" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 27 ,"ooo-motionpath-peanut" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 32 ,"ooo-motionpath-clover" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 19 ,"ooo-motionpath-pointy-star" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 30 ,"ooo-motionpath-swoosh" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 22 ,"ooo-motionpath-vertical-figure-8" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 35 ,"ooo-motionpath-left" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 63 ,"ooo-motionpath-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 55 ,"ooo-motionpath-spiral-left" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 46 ,"ooo-motionpath-spiral-right" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 40 ,"ooo-motionpath-sine-wave" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 59 ,"ooo-motionpath-s-curve-1" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 39 ,"ooo-motionpath-s-curve-2" },
+ { css::presentation::EffectPresetClass::MOTIONPATH, 45 ,"ooo-motionpath-heartbeat" },
+
+ { 0,0,nullptr }
+ };
+
+ return aList;
+};
+
+OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType )
+{
+ const char* pStr = nullptr;
+
+ if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) )
+ {
+ // skip wheel effect
+ if( nPresetId != 21 )
+ {
+ if( nPresetId == 5 )
+ {
+ // checkerboard
+ switch( nPresetSubType )
+ {
+ case 5: pStr = "downward"; break;
+ case 10: pStr = "across"; break;
+ }
+ }
+ else if( nPresetId == 17 )
+ {
+ // stretch
+ if( nPresetSubType == 10 )
+ pStr = "across";
+ }
+ else if( nPresetId == 18 )
+ {
+ // strips
+ switch( nPresetSubType )
+ {
+ case 3: pStr = "right-to-top"; break;
+ case 6: pStr = "right-to-bottom"; break;
+ case 9: pStr = "left-to-top"; break;
+ case 12: pStr = "left-to-bottom"; break;
+ }
+ }
+
+ if( pStr == nullptr )
+ {
+ const convert_subtype* p = convert_subtype::getList();
+
+ while( p->mpStrSubType )
+ {
+ if( p->mnID == nPresetSubType )
+ {
+ pStr = p->mpStrSubType;
+ break;
+ }
+ p++;
+ }
+ }
+ }
+ }
+
+ if( pStr )
+ return OUString::createFromAscii( pStr );
+ else
+ return OUString::number( nPresetSubType );
+}
+
+ CommonTimeNodeContext::CommonTimeNodeContext(
+ FragmentHandler2 const & rParent,
+ sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, pNode )
+ , mbIterate( false )
+ {
+ AttributeList attribs( xAttribs );
+ sal_Int32 nInt; // some temporary int value for float conversions
+
+ NodePropertyMap & aProps = pNode->getNodeProperties();
+ TimeNode::UserDataMap & aUserData = pNode->getUserData();
+
+ if( attribs.hasAttribute( XML_accel ) )
+ {
+ double dPercent = ::oox::drawingml::GetPositiveFixedPercentage( xAttribs->getOptionalValue( XML_accel ) );
+ aProps[ NP_ACCELERATION ] <<= dPercent;
+ }
+
+ if( attribs.hasAttribute( XML_afterEffect ) )
+ {
+ aUserData[ "after-effect" ]
+ <<= attribs.getBool( XML_afterEffect, false );
+ }
+ aProps[ NP_AUTOREVERSE ] <<= attribs.getBool( XML_autoRev, false );
+
+ // TODO
+ if( attribs.hasAttribute( XML_bldLvl ) )
+ {
+ attribs.getInteger( XML_bldLvl, 0 );
+ }
+ if( attribs.hasAttribute( XML_decel ) )
+ {
+ double dPercent = ::oox::drawingml::GetPositiveFixedPercentage( xAttribs->getOptionalValue( XML_decel ) );
+ aProps[ NP_DECELERATE ] <<= dPercent;
+ }
+ // TODO
+ if( attribs.hasAttribute( XML_display ) )
+ {
+ aProps[ NP_DISPLAY ] <<= attribs.getBool( XML_display, true );
+ }
+ if( attribs.hasAttribute( XML_dur ) )
+ {
+ aProps[ NP_DURATION ] = GetTime( xAttribs->getOptionalValue( XML_dur) );
+ }
+ // TODO
+ if( attribs.hasAttribute( XML_evtFilter ) )
+ {
+ xAttribs->getOptionalValue( XML_evtFilter );
+ }
+ // ST_TLTimeNodeFillType
+ if( attribs.hasAttribute( XML_fill ) )
+ {
+ nInt = xAttribs->getOptionalValueToken( XML_fill, 0 );
+ if( nInt != 0 )
+ {
+ sal_Int16 nEnum;
+ switch( nInt )
+ {
+ case XML_remove:
+ nEnum = AnimationFill::REMOVE;
+ break;
+ case XML_freeze:
+ nEnum = AnimationFill::FREEZE;
+ break;
+ case XML_hold:
+ nEnum = AnimationFill::HOLD;
+ break;
+ case XML_transition:
+ nEnum = AnimationFill::TRANSITION;
+ break;
+ default:
+ nEnum = AnimationFill::DEFAULT;
+ break;
+ }
+ aProps[ NP_FILL ] <<= nEnum;
+ }
+ }
+ if( attribs.hasAttribute( XML_grpId ) )
+ {
+ attribs.getUnsigned( XML_grpId, 0 );
+ }
+ // ST_TLTimeNodeID
+ if( attribs.hasAttribute( XML_id ) )
+ {
+ sal_uInt32 nId = attribs.getUnsigned( XML_id, 0 );
+ pNode->setId( nId );
+ }
+ // ST_TLTimeNodeMasterRelation
+ nInt = xAttribs->getOptionalValueToken( XML_masterRel, 0 );
+ if( nInt )
+ {
+ // TODO
+ switch(nInt)
+ {
+ case XML_sameClick:
+ case XML_lastClick:
+ case XML_nextClick:
+ break;
+ }
+ }
+
+ // TODO
+ if( attribs.hasAttribute( XML_nodePh ) )
+ {
+ attribs.getBool( XML_nodePh, false );
+ }
+ // ST_TLTimeNodeType
+ nInt = xAttribs->getOptionalValueToken( XML_nodeType, 0 );
+ if( nInt != 0 )
+ {
+ sal_Int16 nEnum;
+ switch( nInt )
+ {
+ case XML_clickEffect:
+ case XML_clickPar:
+ nEnum = EffectNodeType::ON_CLICK;
+ break;
+ case XML_withEffect:
+ case XML_withGroup:
+ nEnum = EffectNodeType::WITH_PREVIOUS;
+ break;
+ case XML_mainSeq:
+ nEnum = EffectNodeType::MAIN_SEQUENCE;
+ break;
+ case XML_interactiveSeq:
+ nEnum = EffectNodeType::INTERACTIVE_SEQUENCE;
+ break;
+ case XML_afterGroup:
+ case XML_afterEffect:
+ nEnum = EffectNodeType::AFTER_PREVIOUS;
+ break;
+ case XML_tmRoot:
+ nEnum = EffectNodeType::TIMING_ROOT;
+ break;
+ default:
+ nEnum = EffectNodeType::DEFAULT;
+ break;
+ }
+ aUserData[ "node-type" ] <<= nEnum;
+ }
+
+ // ST_TLTimeNodePresetClassType
+ nInt = xAttribs->getOptionalValueToken( XML_presetClass, 0 );
+ if( nInt != 0 )
+ {
+ sal_Int16 nEffectPresetClass = 0;
+ // TODO put that in a function
+ switch( nInt )
+ {
+ case XML_entr:
+ nEffectPresetClass = EffectPresetClass::ENTRANCE;
+ break;
+ case XML_exit:
+ nEffectPresetClass = EffectPresetClass::EXIT;
+ break;
+ case XML_emph:
+ nEffectPresetClass = EffectPresetClass::EMPHASIS;
+ break;
+ case XML_path:
+ nEffectPresetClass = EffectPresetClass::MOTIONPATH;
+ break;
+ case XML_verb:
+ // TODO check that the value below is correct
+ nEffectPresetClass = EffectPresetClass::OLEACTION;
+ break;
+ case XML_mediacall:
+ nEffectPresetClass = EffectPresetClass::MEDIACALL;
+ break;
+ default:
+ nEffectPresetClass = 0;
+ break;
+ }
+ aUserData[ "preset-class" ] <<= nEffectPresetClass;
+ if( attribs.hasAttribute( XML_presetID ) )
+ {
+ sal_Int32 nPresetId = attribs.getInteger( XML_presetID, 0 );
+ const preset_mapping* p = preset_mapping::getList();
+ while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) )
+ p++;
+
+ aUserData[ "preset-id" ]
+ <<= OUString::createFromAscii( p->mpStrPresetId );
+ sal_Int32 nPresetSubType = attribs.getInteger( XML_presetSubtype, 0 );
+ if( nPresetSubType )
+ {
+ aUserData[ "preset-sub-type" ] <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType );
+ }
+ }
+ }
+ if( attribs.hasAttribute( XML_repeatCount ) )
+ {
+ aProps[ NP_REPEATCOUNT ] = GetTime( xAttribs->getOptionalValue( XML_repeatCount ) );
+ }
+ /* see pptinanimation */
+// aProps[ NP_REPEATCOUNT ] <<= (fCount < ((float)3.40282346638528860e+38)) ? makeAny( (double)fCount ) : makeAny( Timing_INDEFINITE );
+ if( attribs.hasAttribute( XML_repeatDur ) )
+ {
+ aProps[ NP_REPEATDURATION ] = GetTime( xAttribs->getOptionalValue( XML_repeatDur ) );
+ }
+ // TODO repeatDur is otherwise the same as dur. What shall we do? -- Hub
+
+ // ST_TLTimeNodeRestartType
+ nInt = xAttribs->getOptionalValueToken( XML_restart, 0 );
+ if( nInt != 0 )
+ {
+ // TODO put that in a function
+ sal_Int16 nEnum;
+ switch( nInt )
+ {
+ case XML_always:
+ nEnum = AnimationRestart::ALWAYS;
+ break;
+ case XML_whenNotActive:
+ nEnum = AnimationRestart::WHEN_NOT_ACTIVE;
+ break;
+ case XML_never:
+ nEnum = AnimationRestart::NEVER;
+ break;
+ default:
+ nEnum = AnimationRestart::DEFAULT;
+ break;
+ }
+ aProps[ NP_RESTART ] <<= nEnum;
+ }
+ // ST_Percentage TODO
+ xAttribs->getOptionalValue( XML_spd /*"10000" */ );
+ // ST_TLTimeNodeSyncType TODO
+ xAttribs->getOptionalValue( XML_syncBehavior );
+ // TODO (string)
+ xAttribs->getOptionalValue( XML_tmFilter );
+ }
+
+ CommonTimeNodeContext::~CommonTimeNodeContext( ) noexcept
+ {
+ }
+
+ void CommonTimeNodeContext::onEndElement()
+ {
+ if( isCurrentElement( PPT_TOKEN( iterate ) ) )
+ {
+ mbIterate = false;
+ }
+ }
+
+ ::oox::core::ContextHandlerRef CommonTimeNodeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( childTnLst ):
+ case PPT_TOKEN( subTnLst ):
+ return new TimeNodeListContext( *this, mpNode->getChildren() );
+
+ case PPT_TOKEN( stCondLst ):
+ return new CondListContext( *this, aElementToken, mpNode, mpNode->getStartCondition() );
+ case PPT_TOKEN( endCondLst ):
+ return new CondListContext( *this, aElementToken, mpNode, mpNode->getEndCondition() );
+
+ case PPT_TOKEN( endSync ):
+ return new CondContext( *this, rAttribs.getFastAttributeList(), mpNode, mpNode->getEndSyncValue() );
+ case PPT_TOKEN( iterate ):
+ {
+ sal_Int32 nVal = rAttribs.getToken( XML_type, XML_el );
+ if( nVal != 0 )
+ {
+ // TODO put that in a function
+ sal_Int16 nEnum;
+ switch( nVal )
+ {
+ case XML_el:
+ nEnum = TextAnimationType::BY_PARAGRAPH;
+ break;
+ case XML_lt:
+ nEnum = TextAnimationType::BY_LETTER;
+ break;
+ case XML_wd:
+ nEnum = TextAnimationType::BY_WORD;
+ break;
+ default:
+ // default is BY_WORD. See Ppt97Animation::GetTextAnimationType()
+ // in sd/source/filter/ppt/ppt97animations.cxx:297
+ nEnum = TextAnimationType::BY_WORD;
+ break;
+ }
+ mpNode->getNodeProperties()[ NP_ITERATETYPE ] <<= nEnum;
+ }
+ // in case of exception we ignore the whole tag.
+ // TODO what to do with this
+ /*bool bBackwards =*/ rAttribs.getBool( XML_backwards, false );
+ mbIterate = true;
+ return this;
+ }
+ case PPT_TOKEN( tmAbs ):
+ if( mbIterate )
+ {
+ double fTime = rAttribs.getUnsigned( XML_val, 0 ) / 1000.0; // convert ms. to second.
+ mpNode->getNodeProperties()[NP_ITERATEINTERVAL] <<= fTime;
+ }
+ return this;
+ case PPT_TOKEN( tmPct ):
+ if( mbIterate )
+ {
+ // TODO: should use duration to get iterate interval in second.
+ double fPercent = static_cast<double>(rAttribs.getUnsigned( XML_val, 0 )) / 100000.0;
+ mpNode->getNodeProperties()[ NP_ITERATEINTERVAL ] <<= fPercent;
+ }
+ return this;
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/commontimenodecontext.hxx b/oox/source/ppt/commontimenodecontext.hxx
new file mode 100644
index 000000000..80ca74926
--- /dev/null
+++ b/oox/source/ppt/commontimenodecontext.hxx
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_COMMONTIMENODECONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_COMMONTIMENODECONTEXT_HXX
+
+#include <oox/ppt/timenode.hxx>
+#include <oox/ppt/timenodelistcontext.hxx>
+
+namespace oox::ppt {
+
+ /** CT_TLCommonTimeNodeData */
+ class CommonTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ CommonTimeNodeContext( ::oox::core::FragmentHandler2 const & rParent, sal_Int32 aElement, const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttribs, const TimeNodePtr & pNode);
+ virtual ~CommonTimeNodeContext( ) noexcept override;
+
+ virtual void onEndElement() override;
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ bool mbIterate;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/conditioncontext.cxx b/oox/source/ppt/conditioncontext.cxx
new file mode 100644
index 000000000..650d7ef9c
--- /dev/null
+++ b/oox/source/ppt/conditioncontext.cxx
@@ -0,0 +1,182 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "conditioncontext.hxx"
+
+#include <com/sun/star/animations/AnimationEndSync.hpp>
+#include <com/sun/star/animations/EventTrigger.hpp>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/ppt/animationspersist.hxx>
+#include "animationtypes.hxx"
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+#include "timetargetelementcontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::animations;
+
+namespace oox::ppt {
+
+ CondContext::CondContext( FragmentHandler2 const & rParent, const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode, AnimationCondition & aValue )
+ : TimeNodeContext( rParent, PPT_TOKEN( cond ), pNode )
+ , maCond( aValue )
+ {
+ maEvent.Trigger = EventTrigger::NONE;
+ maEvent.Repeat = 0;
+
+ AttributeList attribs( xAttribs );
+ if( attribs.hasAttribute( XML_evt ) )
+ {
+ sal_Int32 nEvent = xAttribs->getOptionalValueToken( XML_evt, 0 );
+ switch( nEvent )
+ {
+ case XML_onBegin:
+ maEvent.Trigger = EventTrigger::ON_BEGIN;
+ break;
+ case XML_onEnd:
+ maEvent.Trigger = EventTrigger::ON_END;
+ break;
+ case XML_begin:
+ maEvent.Trigger = EventTrigger::BEGIN_EVENT;
+ break;
+ case XML_end:
+ maEvent.Trigger = EventTrigger::END_EVENT;
+ break;
+ case XML_onClick:
+ maEvent.Trigger = EventTrigger::ON_CLICK;
+ break;
+ case XML_onDblClick:
+ maEvent.Trigger = EventTrigger::ON_DBL_CLICK;
+ break;
+ case XML_onMouseOver:
+ maEvent.Trigger = EventTrigger::ON_MOUSE_ENTER;
+ break;
+ case XML_onMouseOut:
+ maEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE;
+ break;
+ case XML_onNext:
+ maEvent.Trigger = EventTrigger::ON_NEXT;
+ break;
+ case XML_onPrev:
+ maEvent.Trigger = EventTrigger::ON_PREV;
+ break;
+ case XML_onStopAudio:
+ maEvent.Trigger = EventTrigger::ON_STOP_AUDIO;
+ break;
+ default:
+ break;
+ }
+ }
+ if( attribs.hasAttribute( XML_delay ) || ( maEvent.Trigger == EventTrigger::NONE ) )
+ {
+ maEvent.Offset = GetTime( xAttribs->getOptionalValue( XML_delay ) );
+ }
+ }
+
+ CondContext::~CondContext( ) noexcept
+ {
+ if( maCond.mnType == 0 || maCond.mnType == PPT_TOKEN(tn))
+ {
+ maCond.maValue = (maEvent.Trigger == EventTrigger::NONE) ? maEvent.Offset : Any( maEvent );
+ }
+ }
+
+ ::oox::core::ContextHandlerRef CondContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( rtn ):
+ {
+ // ST_TLTriggerRuntimeNode { first, last, all }
+ sal_Int32 aTok;
+ sal_Int16 nEnum;
+ aTok = rAttribs.getToken( XML_val, XML_first );
+ switch( aTok )
+ {
+ case XML_first:
+ nEnum = AnimationEndSync::FIRST;
+ break;
+ case XML_last:
+ nEnum = AnimationEndSync::LAST;
+ break;
+ case XML_all:
+ nEnum = AnimationEndSync::ALL;
+ break;
+ default:
+ break;
+ }
+ maCond.mnType = aElementToken;
+ maCond.maValue <<= nEnum;
+ return this;
+ }
+ case PPT_TOKEN( tn ):
+ {
+ maCond.mnType = aElementToken;
+ // Convert the node id string to XAnimationNode later
+ maEvent.Source <<= rAttribs.getString(XML_val, OUString());
+ return this;
+ }
+ case PPT_TOKEN( tgtEl ):
+ // CT_TLTimeTargetElement
+ return new TimeTargetElementContext( *this, maCond.getTarget() );
+ default:
+ break;
+ }
+
+ return this;
+
+ }
+
+ /** CT_TLTimeConditionList */
+ CondListContext::CondListContext(
+ FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const TimeNodePtr & pNode,
+ AnimationConditionList & aCond )
+ : TimeNodeContext( rParent, aElement, pNode )
+ , maConditions( aCond )
+ {
+ }
+
+ CondListContext::~CondListContext( )
+ noexcept
+ {
+ }
+
+ ::oox::core::ContextHandlerRef CondListContext::onCreateContext( sal_Int32 aElement, const AttributeList& rAttribs )
+ {
+ switch( aElement )
+ {
+ case PPT_TOKEN( cond ):
+ // add a condition to the list
+ maConditions.emplace_back( );
+ return new CondContext( *this, rAttribs.getFastAttributeList(), mpNode, maConditions.back() );
+ default:
+ break;
+ }
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/conditioncontext.hxx b/oox/source/ppt/conditioncontext.hxx
new file mode 100644
index 000000000..fd8d4dd10
--- /dev/null
+++ b/oox/source/ppt/conditioncontext.hxx
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_CONDITIONCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_CONDITIONCONTEXT_HXX
+
+#include <com/sun/star/animations/Event.hpp>
+
+#include <oox/ppt/timenode.hxx>
+#include <oox/ppt/timenodelistcontext.hxx>
+#include <oox/ppt/animationspersist.hxx>
+
+namespace oox::ppt {
+
+ /** CT_TLTimeCondition */
+ class CondContext
+ : public TimeNodeContext
+ {
+ public:
+ CondContext( ::oox::core::FragmentHandler2 const & rParent,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode, AnimationCondition & aCond );
+ virtual ~CondContext( ) noexcept override;
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ css::animations::Event maEvent;
+ AnimationCondition & maCond;
+ };
+
+ /** CT_TLTimeConditionList */
+ class CondListContext
+ : public TimeNodeContext
+ {
+ public:
+ CondListContext( ::oox::core::FragmentHandler2 const & rParent,
+ sal_Int32 aElement,
+ const TimeNodePtr & pNode, AnimationConditionList & aCondList );
+ virtual ~CondListContext( ) noexcept override;
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ AnimationConditionList & maConditions;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/customshowlistcontext.cxx b/oox/source/ppt/customshowlistcontext.cxx
new file mode 100644
index 000000000..1e6befd63
--- /dev/null
+++ b/oox/source/ppt/customshowlistcontext.cxx
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/customshowlistcontext.hxx>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+namespace {
+
+class CustomShowContext : public ::oox::core::FragmentHandler2
+{
+ std::vector< CustomShow >& mrCustomShowList;
+
+public:
+ CustomShowContext( ::oox::core::FragmentHandler2 const & rParent,
+ const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttribs,
+ std::vector< CustomShow >& rCustomShowList );
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+};
+
+}
+
+CustomShowContext::CustomShowContext( FragmentHandler2 const & rParent,
+ const Reference< XFastAttributeList >& rxAttribs,
+ std::vector< CustomShow >& rCustomShowList )
+: FragmentHandler2( rParent )
+, mrCustomShowList( rCustomShowList )
+{
+ CustomShow aCustomShow;
+ aCustomShow.maCustomShowName = rxAttribs->getOptionalValue( XML_name );
+ aCustomShow.mnId = rxAttribs->getOptionalValue( XML_id );
+ mrCustomShowList.push_back(aCustomShow);
+}
+
+::oox::core::ContextHandlerRef CustomShowContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( sld ) :
+ mrCustomShowList.back().maSldLst.push_back(
+ getRelations()
+ .getRelationFromRelId(rAttribs.getString(R_TOKEN(id), OUString()))
+ ->maTarget);
+ return this;
+ default:
+ break;
+ }
+
+ return this;
+}
+
+CustomShowListContext::CustomShowListContext( FragmentHandler2 const & rParent,
+ std::vector< CustomShow >& rCustomShowList )
+: FragmentHandler2( rParent )
+, mrCustomShowList( rCustomShowList )
+{
+}
+
+CustomShowListContext::~CustomShowListContext( )
+{
+}
+
+::oox::core::ContextHandlerRef CustomShowListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( custShow ) :
+ {
+ return new CustomShowContext( *this, rAttribs.getFastAttributeList(), mrCustomShowList );
+ }
+ default:
+ break;
+ }
+
+ return this;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/extdrawingfragmenthandler.cxx b/oox/source/ppt/extdrawingfragmenthandler.cxx
new file mode 100644
index 000000000..9aad170c1
--- /dev/null
+++ b/oox/source/ppt/extdrawingfragmenthandler.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "extdrawingfragmenthandler.hxx"
+
+#include <oox/ppt/pptshapegroupcontext.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+namespace oox::ppt {
+
+ExtDrawingFragmentHandler::ExtDrawingFragmentHandler( XmlFilterBase& rFilter,
+ const OUString& rFragmentPath,
+ const oox::ppt::SlidePersistPtr& rSlidePersistPtr,
+ const oox::ppt::ShapeLocation eShapeLocation,
+ oox::drawingml::ShapePtr const & pGroupShapePtr,
+ oox::drawingml::ShapePtr const & pShapePtr)
+ : FragmentHandler2( rFilter, rFragmentPath ),
+ mpSlidePersistPtr (rSlidePersistPtr ),
+ meShapeLocation( eShapeLocation ),
+ mpGroupShapePtr( pGroupShapePtr ),
+ mpShapePtr( pShapePtr )
+{
+}
+
+ExtDrawingFragmentHandler::~ExtDrawingFragmentHandler( ) noexcept
+{
+ // Empty DrawingML fallback, need to warn the user at the end.
+ if (mpShapePtr && mpShapePtr->getChildren().empty())
+ getFilter().setMissingExtDrawing();
+}
+
+ContextHandlerRef
+ExtDrawingFragmentHandler::onCreateContext( ::sal_Int32 aElement,
+ const AttributeList& )
+{
+ switch( aElement )
+ {
+ case DSP_TOKEN( drawing ):
+ break;
+ case DSP_TOKEN( spTree ):
+ return new PPTShapeGroupContext(
+ *this, mpSlidePersistPtr, meShapeLocation, mpGroupShapePtr,
+ mpShapePtr );
+ default:
+ break;
+ }
+
+ return this;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/extdrawingfragmenthandler.hxx b/oox/source/ppt/extdrawingfragmenthandler.hxx
new file mode 100644
index 000000000..22406f3d9
--- /dev/null
+++ b/oox/source/ppt/extdrawingfragmenthandler.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_EXTDRAWINGFRAGMENTHANDLER_HXX
+#define INCLUDED_OOX_SOURCE_PPT_EXTDRAWINGFRAGMENTHANDLER_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/ppt/slidepersist.hxx>
+
+namespace oox::ppt {
+
+class ExtDrawingFragmentHandler : public ::oox::core::FragmentHandler2
+{
+public:
+ ExtDrawingFragmentHandler( oox::core::XmlFilterBase& rFilter, const OUString& rFragmentPath,
+ const oox::ppt::SlidePersistPtr& rSlidePersistPtr,
+ const oox::ppt::ShapeLocation eShapeLocation,
+ oox::drawingml::ShapePtr const & pGroupShapePtr,
+ oox::drawingml::ShapePtr const & pShapePtr );
+ virtual ~ExtDrawingFragmentHandler() noexcept override;
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( ::sal_Int32 Element, const AttributeList& rAttribs ) override;
+
+private:
+ const oox::ppt::SlidePersistPtr mpSlidePersistPtr;
+ const oox::ppt::ShapeLocation meShapeLocation;
+ oox::drawingml::ShapePtr mpGroupShapePtr;
+ oox::drawingml::ShapePtr mpShapePtr;
+};
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/headerfootercontext.cxx b/oox/source/ppt/headerfootercontext.cxx
new file mode 100644
index 000000000..2a51fdafd
--- /dev/null
+++ b/oox/source/ppt/headerfootercontext.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "headerfootercontext.hxx"
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+ HeaderFooterContext::HeaderFooterContext( FragmentHandler2 const & rParent,
+ const AttributeList& rAttribs, HeaderFooter& rHeaderFooter )
+ : FragmentHandler2( rParent )
+ {
+ if ( rAttribs.hasAttribute( XML_sldNum ) )
+ {
+ rHeaderFooter.mbSlideNumber = rAttribs.getBool( XML_sldNum, true );
+ }
+ if ( rAttribs.hasAttribute( XML_hdr ) )
+ {
+ rHeaderFooter.mbHeader = rAttribs.getBool( XML_hdr, true );
+ }
+ if ( rAttribs.hasAttribute( XML_ftr ) )
+ {
+ rHeaderFooter.mbFooter = rAttribs.getBool( XML_ftr, true );
+ }
+ if ( rAttribs.hasAttribute( XML_dt ) )
+ {
+ rHeaderFooter.mbDateTime = rAttribs.getBool( XML_dt, true );
+ }
+ }
+
+ HeaderFooterContext::~HeaderFooterContext( )
+ {
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/headerfootercontext.hxx b/oox/source/ppt/headerfootercontext.hxx
new file mode 100644
index 000000000..9b93fb5f1
--- /dev/null
+++ b/oox/source/ppt/headerfootercontext.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_HEADERFOOTERCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_HEADERFOOTERCONTEXT_HXX
+
+#include <oox/ppt/headerfooter.hxx>
+#include <oox/core/fragmenthandler2.hxx>
+
+namespace oox::ppt {
+
+ /** CT_HeaderFooter */
+ class HeaderFooterContext : public ::oox::core::FragmentHandler2
+ {
+ public:
+ HeaderFooterContext( ::oox::core::FragmentHandler2 const & rParent,
+ const AttributeList& rAttribs, HeaderFooter& rHeaderFooter );
+
+ virtual ~HeaderFooterContext( ) override;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/layoutfragmenthandler.cxx b/oox/source/ppt/layoutfragmenthandler.cxx
new file mode 100644
index 000000000..9d95b6ecc
--- /dev/null
+++ b/oox/source/ppt/layoutfragmenthandler.cxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "headerfootercontext.hxx"
+#include <oox/ppt/layoutfragmenthandler.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+#include <utility>
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+// CT_SlideLayout
+
+LayoutFragmentHandler::LayoutFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath,
+ const SlidePersistPtr& pMasterPersistPtr)
+ : SlideFragmentHandler(rFilter, rFragmentPath, pMasterPersistPtr, Layout)
+{
+}
+
+LayoutFragmentHandler::~LayoutFragmentHandler()
+{
+
+}
+
+ContextHandlerRef LayoutFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( sldLayout ): // CT_SlideLayout
+ {
+ mpSlidePersistPtr->setLayoutValueToken( rAttribs.getToken( XML_type, 0 ) ); // CT_SlideLayoutType
+
+ OptValue< bool > aShowMasterShapes = rAttribs.getBool( XML_showMasterSp );
+ if( aShowMasterShapes.has() && !aShowMasterShapes.get() ) {
+ mpSlidePersistPtr->hideShapesAsMasterShapes();
+ }
+ break;
+ }
+ case PPT_TOKEN( hf ): // CT_HeaderFooter
+ return new HeaderFooterContext( *this, rAttribs, mpSlidePersistPtr->getHeaderFooter() );
+ default:
+ return SlideFragmentHandler::onCreateContext( aElementToken, rAttribs );
+ }
+ return this;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptfilterhelpers.cxx b/oox/source/ppt/pptfilterhelpers.cxx
new file mode 100644
index 000000000..054bf6260
--- /dev/null
+++ b/oox/source/ppt/pptfilterhelpers.cxx
@@ -0,0 +1,422 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/animations/TransitionType.hpp>
+#include <com/sun/star/animations/TransitionSubType.hpp>
+#include <com/sun/star/animations/ValuePair.hpp>
+#include <com/sun/star/awt/FontWeight.hpp>
+#include <com/sun/star/awt/FontUnderline.hpp>
+#include <com/sun/star/awt/FontSlant.hpp>
+#include <com/sun/star/drawing/LineStyle.hpp>
+#include <com/sun/star/drawing/FillStyle.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <oox/ppt/pptfilterhelpers.hxx>
+#include <tools/color.hxx>
+#include <o3tl/string_view.hxx>
+
+namespace {
+ int lcl_gethex(int nChar)
+ {
+ if (nChar >= '0' && nChar <= '9')
+ return nChar - '0';
+ else if (nChar >= 'a' && nChar <= 'f')
+ return nChar - 'a' + 10;
+ else if (nChar >= 'A' && nChar <= 'F')
+ return nChar - 'A' + 10;
+ else
+ return 0;
+ }
+}
+
+namespace oox::ppt {
+
+ const ImplAttributeNameConversion *getAttributeConversionList()
+ {
+ static const ImplAttributeNameConversion aList[] =
+ {
+ { AnimationAttributeEnum::PPT_X, "ppt_x", "X" },
+ { AnimationAttributeEnum::PPT_Y, "ppt_y", "Y" },
+ { AnimationAttributeEnum::PPT_W, "ppt_w", "Width" },
+ { AnimationAttributeEnum::PPT_H, "ppt_h", "Height" },
+ { AnimationAttributeEnum::PPT_C, "ppt_c", "DimColor" },
+ { AnimationAttributeEnum::R, "r", "Rotate" },
+ { AnimationAttributeEnum::XSHEAR, "xshear", "SkewX" },
+ { AnimationAttributeEnum::FILLCOLOR, "fillcolor", "FillColor" },
+ { AnimationAttributeEnum::FILLCOLOR, "fillColor", "FillColor" },
+ { AnimationAttributeEnum::FILLTYPE, "fill.type", "FillStyle" },
+ { AnimationAttributeEnum::FILLON, "fill.on", "FillOn" },
+ { AnimationAttributeEnum::STROKECOLOR, "stroke.color", "LineColor" },
+ { AnimationAttributeEnum::STROKEON, "stroke.on", "LineStyle" },
+ { AnimationAttributeEnum::STYLECOLOR, "style.color", "CharColor" },
+ { AnimationAttributeEnum::STYLEROTATION, "style.rotation", "Rotate" },
+ { AnimationAttributeEnum::FONTWEIGHT, "style.fontWeight", "CharWeight" },
+ { AnimationAttributeEnum::STYLEUNDERLINE, "style.textDecorationUnderline","CharUnderline" },
+ { AnimationAttributeEnum::STYLEFONTFAMILY, "style.fontFamily", "CharFontName" },
+ { AnimationAttributeEnum::STYLEFONTSIZE, "style.fontSize", "CharHeight" },
+ { AnimationAttributeEnum::STYLEFONTSTYLE, "style.fontStyle", "CharPosture" },
+ { AnimationAttributeEnum::STYLEVISIBILITY, "style.visibility", "Visibility" },
+ { AnimationAttributeEnum::STYLEOPACITY, "style.opacity", "Opacity" },
+ { AnimationAttributeEnum::UNKNOWN, nullptr, nullptr }
+ };
+
+ return aList;
+ }
+
+ const transition* transition::getList()
+ {
+ static const transition aList[] =
+ {
+ { "wipe(up)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::TOPTOBOTTOM, true },
+ { "wipe(right)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::LEFTTORIGHT, false },
+ { "wipe(left)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::LEFTTORIGHT, true },
+ { "wipe(down)", css::animations::TransitionType::BARWIPE, css::animations::TransitionSubType::TOPTOBOTTOM, false },
+ { "wheel(1)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::ONEBLADE, true },
+ { "wheel(2)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::TWOBLADEVERTICAL, true },
+ { "wheel(3)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::THREEBLADE, true },
+ { "wheel(4)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::FOURBLADE, true },
+ { "wheel(8)", css::animations::TransitionType::PINWHEELWIPE, css::animations::TransitionSubType::EIGHTBLADE, true },
+ { "strips(downLeft)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALRIGHT, true },
+ { "strips(upLeft)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALLEFT, false },
+ { "strips(downRight)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALLEFT, true },
+ { "strips(upRight)", css::animations::TransitionType::WATERFALLWIPE, css::animations::TransitionSubType::HORIZONTALRIGHT, false },
+ { "barn(inVertical)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::VERTICAL, false },
+ { "barn(outVertical)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::VERTICAL, true },
+ { "barn(inHorizontal)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::HORIZONTAL, false },
+ { "barn(outHorizontal)", css::animations::TransitionType::BARNDOORWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
+ { "randombar(vertical)", css::animations::TransitionType::RANDOMBARWIPE, css::animations::TransitionSubType::VERTICAL, true},
+ { "randombar(horizontal)", css::animations::TransitionType::RANDOMBARWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
+ { "checkerboard(down)", css::animations::TransitionType::CHECKERBOARDWIPE, css::animations::TransitionSubType::DOWN, true},
+ { "checkerboard(across)", css::animations::TransitionType::CHECKERBOARDWIPE, css::animations::TransitionSubType::ACROSS, true },
+ { "plus(out)", css::animations::TransitionType::FOURBOXWIPE, css::animations::TransitionSubType::CORNERSIN, false },
+ { "plus(in)", css::animations::TransitionType::FOURBOXWIPE, css::animations::TransitionSubType::CORNERSIN, true },
+ { "diamond(out)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::DIAMOND, true },
+ { "diamond(in)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::DIAMOND, false },
+ { "circle(out)", css::animations::TransitionType::ELLIPSEWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
+ { "circle(in)", css::animations::TransitionType::ELLIPSEWIPE, css::animations::TransitionSubType::HORIZONTAL, false },
+ { "box(out)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::RECTANGLE, true },
+ { "box(in)", css::animations::TransitionType::IRISWIPE, css::animations::TransitionSubType::RECTANGLE, false },
+ { "wedge", css::animations::TransitionType::FANWIPE, css::animations::TransitionSubType::CENTERTOP, true },
+ { "blinds(vertical)", css::animations::TransitionType::BLINDSWIPE, css::animations::TransitionSubType::VERTICAL, true },
+ { "blinds(horizontal)", css::animations::TransitionType::BLINDSWIPE, css::animations::TransitionSubType::HORIZONTAL, true },
+ { "fade", css::animations::TransitionType::FADE, css::animations::TransitionSubType::CROSSFADE, true },
+ { "slide(fromTop)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMTOP, true },
+ { "slide(fromRight)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMRIGHT, true },
+ { "slide(fromLeft)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMLEFT, true },
+ { "slide(fromBottom)", css::animations::TransitionType::SLIDEWIPE, css::animations::TransitionSubType::FROMBOTTOM, true },
+ { "dissolve", css::animations::TransitionType::DISSOLVE, css::animations::TransitionSubType::DEFAULT, true },
+ { "image", css::animations::TransitionType::DISSOLVE, css::animations::TransitionSubType::DEFAULT, true }, // TODO
+ { nullptr, 0, 0, false }
+ };
+
+ return aList;
+ }
+
+ const transition* transition::find( std::u16string_view rName )
+ {
+ const transition* p = transition::getList();
+
+ while( p->mpName )
+ {
+ if( o3tl::equalsAscii( rName, p->mpName ) )
+ return p;
+
+ p++;
+ }
+
+ return nullptr;
+ }
+
+ bool convertMeasure(OUString& rString)
+ {
+ bool bRet = false;
+
+ const char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", nullptr };
+ const char* pDest[] = { "x", "y", "width", "height", nullptr };
+
+ /* here we want to substitute all occurrences of
+ * [#]ppt_[xyhw] with
+ * x,y,height and width respectively
+ */
+ sal_Int32 nIndex = 0;
+
+ const char** ps = pSource;
+ const char** pd = pDest;
+
+ while (*ps)
+ {
+ const OUString aSearch(OUString::createFromAscii(*ps));
+ while ((nIndex = rString.indexOf(aSearch, nIndex)) != -1)
+ {
+ sal_Int32 nLength = aSearch.getLength();
+ if (nIndex && (rString[nIndex - 1] == '#'))
+ {
+ nIndex--;
+ nLength++;
+ }
+
+ const OUString aNew(OUString::createFromAscii(*pd));
+ rString = rString.replaceAt(nIndex, nLength, aNew);
+ nIndex += aNew.getLength();
+ bRet = true;
+ }
+ ps++;
+ pd++;
+ }
+
+ return bRet;
+ }
+
+ bool convertAnimationValue(AnimationAttributeEnum eAttribute, css::uno::Any& rValue)
+ {
+ using css::animations::ValuePair;
+ bool bRet = false;
+ switch (eAttribute)
+ {
+ case AnimationAttributeEnum::PPT_X:
+ case AnimationAttributeEnum::PPT_Y:
+ case AnimationAttributeEnum::PPT_W:
+ case AnimationAttributeEnum::PPT_H:
+ {
+ OUString aString;
+
+ if (rValue.getValueType() == cppu::UnoType<ValuePair>::get())
+ {
+ ValuePair aValuePair;
+ if (rValue >>= aValuePair)
+ {
+ if (aValuePair.First >>= aString)
+ {
+ if (convertMeasure(aString))
+ {
+ aValuePair.First <<= aString;
+ bRet = true;
+ }
+ }
+
+ if (aValuePair.Second >>= aString)
+ {
+ if (convertMeasure(aString))
+ {
+ aValuePair.Second <<= aString;
+ bRet = true;
+ }
+ }
+ }
+ }
+ else if (rValue.getValueType() == cppu::UnoType<OUString>::get())
+ {
+ if (rValue >>= aString)
+ {
+ bRet = convertMeasure(aString);
+
+ if (bRet)
+ rValue <<= aString;
+ }
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::XSHEAR:
+ case AnimationAttributeEnum::R:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString.toDouble();
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::STYLEROTATION:
+ {
+ if (rValue.getValueType() == cppu::UnoType<OUString>::get())
+ {
+ OUString aString;
+ rValue >>= aString;
+ rValue <<= static_cast<sal_Int16>(aString.toDouble());
+ bRet = true;
+ }
+ else if (rValue.getValueType() == cppu::UnoType<double>::get())
+ {
+ double fValue = 0.0;
+ rValue >>= fValue;
+ rValue <<= static_cast<sal_Int16>(fValue);
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::FILLCOLOR:
+ case AnimationAttributeEnum::STROKECOLOR:
+ case AnimationAttributeEnum::STYLECOLOR:
+ case AnimationAttributeEnum::PPT_C:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ if (aString.getLength() >= 7 && aString[0] == '#')
+ {
+ Color aColor;
+ aColor.SetRed(static_cast<sal_uInt8>(lcl_gethex(aString[1]) * 16
+ + lcl_gethex(aString[2])));
+ aColor.SetGreen(static_cast<sal_uInt8>(lcl_gethex(aString[3]) * 16
+ + lcl_gethex(aString[4])));
+ aColor.SetBlue(static_cast<sal_uInt8>(lcl_gethex(aString[5]) * 16
+ + lcl_gethex(aString[6])));
+ rValue <<= aColor;
+ bRet = true;
+ }
+ else if (aString.startsWith("rgb("))
+ {
+ aString = aString.copy(4, aString.getLength() - 5);
+ Color aColor;
+ sal_Int32 index = 0;
+ aColor.SetRed(
+ static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(aString, 0, ',', index))));
+ aColor.SetGreen(
+ static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(aString, 0, ',', index))));
+ aColor.SetRed(
+ static_cast<sal_uInt8>(o3tl::toInt32(o3tl::getToken(aString, 0, ',', index))));
+ rValue <<= aColor;
+ bRet = true;
+ }
+ else if (aString.startsWith("hsl("))
+ {
+ sal_Int32 index = 0;
+ sal_Int32 nA = o3tl::toInt32(o3tl::getToken(aString, 0, ',', index));
+ sal_Int32 nB = o3tl::toInt32(o3tl::getToken(aString, 0, ',', index));
+ sal_Int32 nC = o3tl::toInt32(o3tl::getToken(aString, 0, ',', index));
+ css::uno::Sequence<double> aHSL
+ {
+ nA * 360.0 / 255.0,
+ nB / 255.0,
+ nC / 255.0
+ };
+ rValue <<= aHSL;
+ bRet = true;
+ }
+ }
+ }
+ break;
+ case AnimationAttributeEnum::FILLON:
+ {
+ // Slideshow doesn't support FillOn, but we need to convert the value type
+ // so it can be written out again.
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString == "true";
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::FILLTYPE:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString == "solid" ? css::drawing::FillStyle_SOLID
+ : css::drawing::FillStyle_NONE;
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::STROKEON:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString == "true" ? css::drawing::LineStyle_SOLID
+ : css::drawing::LineStyle_NONE;
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::FONTWEIGHT:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString == "bold" ? css::awt::FontWeight::BOLD
+ : css::awt::FontWeight::NORMAL;
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::STYLEFONTSTYLE:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue
+ <<= aString == "italic" ? css::awt::FontSlant_ITALIC : css::awt::FontSlant_NONE;
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::STYLEUNDERLINE:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString == "true" ? css::awt::FontUnderline::SINGLE
+ : css::awt::FontUnderline::NONE;
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::STYLEOPACITY:
+ case AnimationAttributeEnum::STYLEFONTSIZE:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= static_cast<float>(aString.toDouble());
+ bRet = true;
+ }
+ }
+ break;
+
+ case AnimationAttributeEnum::STYLEVISIBILITY:
+ {
+ OUString aString;
+ if (rValue >>= aString)
+ {
+ rValue <<= aString == "visible";
+ bRet = true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return bRet;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptgraphicshapecontext.cxx b/oox/source/ppt/pptgraphicshapecontext.cxx
new file mode 100644
index 000000000..254f44809
--- /dev/null
+++ b/oox/source/ppt/pptgraphicshapecontext.cxx
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/pptshape.hxx>
+#include <oox/ppt/pptgraphicshapecontext.hxx>
+#include <oox/ppt/pptshapepropertiescontext.hxx>
+#include <oox/ppt/slidepersist.hxx>
+#include <drawingml/shapestylecontext.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <drawingml/textbodycontext.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/token/properties.hxx>
+
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+
+namespace oox::ppt {
+
+// CT_Shape
+PPTGraphicShapeContext::PPTGraphicShapeContext( ContextHandler2Helper const & rParent, const SlidePersistPtr& rSlidePersistPtr, const oox::drawingml::ShapePtr& pMasterShapePtr, const oox::drawingml::ShapePtr& pShapePtr )
+: oox::drawingml::GraphicShapeContext( rParent, pMasterShapePtr, pShapePtr )
+, mpSlidePersistPtr( rSlidePersistPtr )
+{
+}
+
+ContextHandlerRef PPTGraphicShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ // nvSpPr CT_ShapeNonVisual begin
+// case NMSP_PPT|XML_drElemPr:
+// break;
+ case PPT_TOKEN(cNvPr):
+ mpShapePtr->setId( rAttribs.getString( XML_id ).get() );
+ mpShapePtr->setName( rAttribs.getString( XML_name ).get() );
+ break;
+ case PPT_TOKEN(ph):
+ {
+ sal_Int32 nSubType( rAttribs.getToken( XML_type, XML_obj ) );
+ mpShapePtr->setSubType( nSubType );
+ OUString sIdx( rAttribs.getString( XML_idx ).get() );
+ bool bHasIdx = !sIdx.isEmpty();
+ sal_Int32 nIdx = sIdx.toInt32();
+ if( rAttribs.hasAttribute( XML_idx ) )
+ mpShapePtr->setSubTypeIndex( nIdx );
+
+ if ( nSubType || bHasIdx )
+ {
+ PPTShape* pPPTShapePtr = dynamic_cast< PPTShape* >( mpShapePtr.get() );
+ if ( pPPTShapePtr )
+ {
+ oox::ppt::ShapeLocation eShapeLocation = pPPTShapePtr->getShapeLocation();
+ oox::drawingml::ShapePtr pPlaceholder;
+
+ if ( bHasIdx && eShapeLocation == Slide )
+ {
+ // TODO: use id to shape map
+ SlidePersistPtr pMasterPersist( mpSlidePersistPtr->getMasterPersist() );
+ if ( pMasterPersist && rAttribs.hasAttribute( XML_idx ) )
+ pPlaceholder = PPTShape::findPlaceholderByIndex( nIdx, pMasterPersist->getShapes()->getChildren() );
+ }
+ if ( !pPlaceholder && ( ( eShapeLocation == Slide ) || ( eShapeLocation == Layout ) ) )
+ {
+ // inheriting properties from placeholder objects by cloning shape
+
+ sal_Int32 nFirstPlaceholder = 0;
+ sal_Int32 nSecondPlaceholder = 0;
+ switch( nSubType )
+ {
+ case XML_ctrTitle : // slide/layout
+ nFirstPlaceholder = XML_ctrTitle;
+ nSecondPlaceholder = XML_title;
+ break;
+ case XML_subTitle : // slide/layout
+ nFirstPlaceholder = XML_subTitle;
+ nSecondPlaceholder = XML_title;
+ break;
+ case XML_obj : // slide/layout
+ nFirstPlaceholder = XML_body;
+ break;
+ case XML_dt : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_sldNum : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_ftr : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_hdr : // notes/notesmaster/handoutmaster
+ case XML_body : // slide/layout/master/notes/notesmaster
+ case XML_title : // slide/layout/master/
+ case XML_chart : // slide/layout
+ case XML_tbl : // slide/layout
+ case XML_clipArt : // slide/layout
+ case XML_dgm : // slide/layout
+ case XML_media : // slide/layout
+ case XML_sldImg : // notes/notesmaster
+ case XML_pic : // slide/layout
+ nFirstPlaceholder = nSubType;
+ break;
+ default:
+ break;
+ }
+ if ( nFirstPlaceholder )
+ {
+ if ( eShapeLocation == Layout ) // for layout objects the referenced object can be found within the same shape tree
+ pPlaceholder = PPTShape::findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
+ pPPTShapePtr->getSubTypeIndex(), mpSlidePersistPtr->getShapes()->getChildren(), true );
+ else if ( eShapeLocation == Slide ) // normal slide shapes have to search within the corresponding master tree for referenced objects
+ {
+ SlidePersistPtr pMasterPersist( mpSlidePersistPtr->getMasterPersist() );
+ if ( pMasterPersist )
+ pPlaceholder = PPTShape::findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
+ pPPTShapePtr->getSubTypeIndex(), pMasterPersist->getShapes()->getChildren() );
+ }
+ }
+ }
+ if ( pPlaceholder )
+ {
+ bool bUseText = true;
+ switch( pPlaceholder->getSubType() )
+ {
+ case XML_title :
+ case XML_body :
+ case XML_ctrTitle :
+ case XML_subTitle :
+ case XML_dt :
+ case XML_sldNum :
+ case XML_ftr :
+ case XML_hdr :
+ case XML_obj :
+ case XML_chart :
+ case XML_tbl :
+ case XML_clipArt :
+ case XML_dgm :
+ case XML_media :
+ case XML_sldImg :
+ case XML_pic :
+ bUseText = false;
+ }
+ pPlaceholder->getShapeProperties().setAnyProperty(
+ PROP_URL, mpShapePtr->getShapeProperties().getProperty(PROP_URL));
+ mpShapePtr->applyShapeReference( *pPlaceholder, bUseText );
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( pPlaceholder.get() );
+ if ( pPPTShape )
+ pPPTShape->setReferenced( true );
+ pPPTShapePtr->setPlaceholder( pPlaceholder );
+ }
+ }
+ }
+ break;
+ }
+ // nvSpPr CT_ShapeNonVisual end
+
+ case PPT_TOKEN(spPr):
+ return new PPTShapePropertiesContext( *this, *mpShapePtr );
+
+ case PPT_TOKEN(style):
+ return new oox::drawingml::ShapeStyleContext( *this, *mpShapePtr );
+
+ case PPT_TOKEN(txBody):
+ {
+ oox::drawingml::TextBodyPtr xTextBody = std::make_shared<oox::drawingml::TextBody>();
+ mpShapePtr->setTextBody( xTextBody );
+ return new oox::drawingml::TextBodyContext( *this, *xTextBody );
+ }
+ }
+
+ return GraphicShapeContext::onCreateContext( aElementToken, rAttribs );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx
new file mode 100644
index 000000000..55e094db6
--- /dev/null
+++ b/oox/source/ppt/pptimport.cxx
@@ -0,0 +1,309 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_wasm_strip.h>
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/document/XUndoManager.hpp>
+#include <com/sun/star/document/XUndoManagerSupplier.hpp>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/sfxecode.hxx>
+#include <svtools/ehdl.hxx>
+#include <tools/urlobj.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <oox/ppt/pptimport.hxx>
+#include <oox/drawingml/chart/chartconverter.hxx>
+#include <oox/dump/pptxdumper.hxx>
+#include <drawingml/table/tablestylelistfragmenthandler.hxx>
+#include <oox/helper/graphichelper.hxx>
+#include <oox/ole/vbaproject.hxx>
+#include <oox/ppt/presentationfragmenthandler.hxx>
+#include <oox/ppt/presPropsfragmenthandler.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace oox::core;
+
+using ::com::sun::star::beans::PropertyValue;
+using ::com::sun::star::lang::XComponent;
+
+namespace oox::ppt {
+
+#if OSL_DEBUG_LEVEL > 0
+XmlFilterBase* PowerPointImport::mpDebugFilterBase = nullptr;
+#endif
+
+PowerPointImport::PowerPointImport( const Reference< XComponentContext >& rxContext ) :
+ XmlFilterBase( rxContext ),
+#if ENABLE_WASM_STRIP_CHART
+ // WASM_CHART change
+ mxChartConv( )
+#else
+ mxChartConv( std::make_shared<::oox::drawingml::chart::ChartConverter>() )
+#endif
+{
+#if OSL_DEBUG_LEVEL > 0
+ mpDebugFilterBase = this;
+#endif
+}
+
+PowerPointImport::~PowerPointImport()
+{
+}
+
+bool PowerPointImport::importDocument()
+{
+ /* to activate the PPTX dumper, define the environment variable
+ OOO_PPTXDUMPER and insert the full path to the file
+ file:///<path-to-oox-module>/source/dump/pptxdumper.ini. */
+ OOX_DUMP_FILE( ::oox::dump::pptx::Dumper );
+
+ uno::Reference< document::XUndoManagerSupplier > xUndoManagerSupplier (getModel(), UNO_QUERY );
+ uno::Reference< util::XLockable > xUndoManager;
+ bool bWasUnLocked = true;
+ if(xUndoManagerSupplier.is())
+ {
+ xUndoManager = xUndoManagerSupplier->getUndoManager();
+ if(xUndoManager.is())
+ {
+ bWasUnLocked = !xUndoManager->isLocked();
+ xUndoManager->lock();
+ }
+ }
+
+ importDocumentProperties();
+
+ OUString aFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( u"officeDocument" );
+ FragmentHandlerRef xPresentationFragmentHandler( new PresentationFragmentHandler( *this, aFragmentPath ) );
+ maTableStyleListPath = xPresentationFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"tableStyles" );
+ const OUString sPresPropsPath
+ = xPresentationFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc(u"presProps");
+
+ bool bRet = importFragment(xPresentationFragmentHandler);
+ if (bRet && !sPresPropsPath.isEmpty())
+ {
+ FragmentHandlerRef xPresPropsFragmentHandler(
+ new PresPropsFragmentHandler(*this, sPresPropsPath));
+ importFragment(xPresPropsFragmentHandler);
+ }
+
+ static bool bNoSmartartWarning = getenv("OOX_NO_SMARTART_WARNING");
+ if (!bNoSmartartWarning && mbMissingExtDrawing)
+ {
+ // Construct a warning message.
+ INetURLObject aURL(getFileUrl());
+ SfxErrorContext aContext(ERRCTX_SFX_OPENDOC, aURL.getName(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset), nullptr, RID_ERRCTX);
+ OUString aWarning;
+ aContext.GetString(ERRCODE_NONE.MakeWarning(), aWarning);
+ aWarning += ":\n" + SvxResId(RID_SVXSTR_WARN_MISSING_SMARTART);
+
+ // Show it.
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Warning, VclButtonsType::Ok,
+ aWarning));
+ xWarn->run();
+ }
+
+ if(xUndoManager.is() && bWasUnLocked)
+ xUndoManager->unlock();
+
+ return bRet;
+
+}
+
+bool PowerPointImport::exportDocument() noexcept
+{
+ return false;
+}
+
+::Color PowerPointImport::getSchemeColor( sal_Int32 nToken ) const
+{
+ ::Color nColor;
+ if ( mpActualSlidePersist )
+ {
+ bool bColorMapped = false;
+ oox::drawingml::ClrMapPtr pClrMapPtr( mpActualSlidePersist->getClrMap() );
+ if ( pClrMapPtr )
+ bColorMapped = pClrMapPtr->getColorMap( nToken );
+
+ if ( !bColorMapped ) // try masterpage mapping
+ {
+ SlidePersistPtr pMasterPersist = mpActualSlidePersist->getMasterPersist();
+ if ( pMasterPersist )
+ {
+ pClrMapPtr = pMasterPersist->getClrMap();
+ if ( pClrMapPtr )
+ pClrMapPtr->getColorMap( nToken );
+ }
+ }
+
+ ::oox::drawingml::ThemePtr pTheme = mpActualSlidePersist->getTheme();
+ if( pTheme )
+ {
+ pTheme->getClrScheme().getColor( nToken, nColor );
+ }
+ else
+ {
+ SAL_WARN("oox", "OOX: PowerPointImport::mpThemePtr is NULL");
+ }
+ }
+ return nColor;
+}
+
+const ::oox::drawingml::Theme* PowerPointImport::getCurrentTheme() const
+{
+ return mpActualSlidePersist ? mpActualSlidePersist->getTheme().get() : nullptr;
+}
+
+std::shared_ptr<::oox::drawingml::Theme> PowerPointImport::getCurrentThemePtr() const
+{
+ return mpActualSlidePersist ? mpActualSlidePersist->getTheme() : std::shared_ptr<::oox::drawingml::Theme>();
+}
+
+sal_Bool SAL_CALL PowerPointImport::filter( const Sequence< PropertyValue >& rDescriptor )
+{
+ if( XmlFilterBase::filter( rDescriptor ) )
+ return true;
+
+ if (isExportFilter())
+ {
+ uno::Sequence<uno::Any> aArguments(comphelper::InitAnyPropertySequence(
+ {
+ {"IsPPTM", uno::Any(exportVBA())},
+ {"IsTemplate", uno::Any(isExportTemplate())},
+ }));
+
+ Reference<css::lang::XMultiServiceFactory> aFactory(getComponentContext()->getServiceManager(), UNO_QUERY_THROW);
+ Reference< XExporter > xExporter(aFactory->createInstanceWithArguments("com.sun.star.comp.Impress.oox.PowerPointExport", aArguments), UNO_QUERY);
+
+ if (Reference<XFilter> xFilter{ xExporter, UNO_QUERY })
+ {
+ Reference<util::XLockable> xUndoManager;
+ bool bWasUnLocked = true;
+ if (Reference<document::XUndoManagerSupplier> xUMS{ getModel(), UNO_QUERY })
+ {
+ xUndoManager = xUMS->getUndoManager();
+ if (xUndoManager.is())
+ {
+ bWasUnLocked = !xUndoManager->isLocked();
+ xUndoManager->lock();
+ }
+ }
+ comphelper::ScopeGuard aGuard([xUndoManager, bWasUnLocked] {
+ if (xUndoManager && bWasUnLocked)
+ xUndoManager->unlock();
+ });
+
+ Reference< XComponent > xDocument = getModel();
+ xExporter->setSourceDocument(xDocument);
+ if (xFilter->filter(rDescriptor))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+::oox::vml::Drawing* PowerPointImport::getVmlDrawing()
+{
+ return mpActualSlidePersist ? mpActualSlidePersist->getDrawing() : nullptr;
+}
+
+oox::drawingml::table::TableStyleListPtr PowerPointImport::getTableStyles()
+{
+ if ( !mpTableStyleList && !maTableStyleListPath.isEmpty() )
+ {
+ mpTableStyleList = std::make_shared<oox::drawingml::table::TableStyleList>( );
+ importFragment( new oox::drawingml::table::TableStyleListFragmentHandler(
+ *this, maTableStyleListPath, *mpTableStyleList ) );
+ }
+ return mpTableStyleList;
+}
+
+::oox::drawingml::chart::ChartConverter* PowerPointImport::getChartConverter()
+{
+ return mxChartConv.get();
+}
+
+namespace {
+
+class PptGraphicHelper : public GraphicHelper
+{
+public:
+ explicit PptGraphicHelper( const PowerPointImport& rFilter );
+ virtual ::Color getSchemeColor( sal_Int32 nToken ) const override;
+ virtual sal_Int32 getDefaultChartAreaFillStyle() const override;
+private:
+ const PowerPointImport& mrFilter;
+};
+
+PptGraphicHelper::PptGraphicHelper( const PowerPointImport& rFilter ) :
+ GraphicHelper( rFilter.getComponentContext(), rFilter.getTargetFrame(), rFilter.getStorage() ),
+ mrFilter( rFilter )
+{
+}
+
+::Color PptGraphicHelper::getSchemeColor( sal_Int32 nToken ) const
+{
+ return mrFilter.getSchemeColor( nToken );
+}
+
+sal_Int32 PptGraphicHelper::getDefaultChartAreaFillStyle() const
+{
+ return XML_noFill;
+}
+
+} // namespace
+
+GraphicHelper* PowerPointImport::implCreateGraphicHelper() const
+{
+ return new PptGraphicHelper( *this );
+}
+
+::oox::ole::VbaProject* PowerPointImport::implCreateVbaProject() const
+{
+ return new ::oox::ole::VbaProject( getComponentContext(), getModel(), u"Impress" );
+}
+
+OUString PowerPointImport::getImplementationName()
+{
+ return "com.sun.star.comp.oox.ppt.PowerPointImport";
+}
+
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
+com_sun_star_comp_oox_ppt_PowerPointImport_get_implementation(
+ uno::XComponentContext* pCtx, uno::Sequence<uno::Any> const& /*rSeq*/)
+{
+ return cppu::acquire(new oox::ppt::PowerPointImport(pCtx));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx
new file mode 100644
index 000000000..2ec4a3fbe
--- /dev/null
+++ b/oox/source/ppt/pptshape.cxx
@@ -0,0 +1,809 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/pptshape.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <drawingml/customshapeproperties.hxx>
+#include <drawingml/textbody.hxx>
+#include <drawingml/textparagraph.hxx>
+#include <drawingml/textfield.hxx>
+#include <editeng/flditem.hxx>
+
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/presentation/ClickAction.hpp>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <sal/log.hxx>
+#include <oox/ppt/slidepersist.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/token/properties.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::awt;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::presentation;
+
+namespace oox::ppt {
+
+PPTShape::PPTShape( const oox::ppt::ShapeLocation eShapeLocation, const char* pServiceName )
+: Shape( pServiceName )
+, meShapeLocation( eShapeLocation )
+, mbReferenced( false )
+, mbHasNoninheritedShapeProperties( false )
+{
+}
+
+PPTShape::~PPTShape()
+{
+}
+
+static const char* lclDebugSubType( sal_Int32 nType )
+{
+ switch (nType) {
+ case XML_ctrTitle :
+ return "ctrTitle";
+ case XML_title :
+ return "title";
+ case XML_subTitle :
+ return "subTitle";
+ case XML_obj :
+ return "obj";
+ case XML_body :
+ return "body";
+ case XML_dt :
+ return "dt";
+ case XML_hdr :
+ return "hdr";
+ case XML_ftr :
+ return "frt";
+ case XML_sldNum :
+ return "sldNum";
+ case XML_sldImg :
+ return "sldImg";
+ }
+
+ return "unknown - please extend lclDebugSubType";
+}
+
+namespace
+{
+bool ShapeHasNoVisualPropertiesOnImport(const oox::ppt::PPTShape& rPPTShape)
+{
+ return !rPPTShape.hasNonInheritedShapeProperties()
+ && !rPPTShape.hasShapeStyleRefs()
+ && !rPPTShape.getTextBody()->hasVisualRunProperties()
+ && !rPPTShape.getTextBody()->hasNoninheritedBodyProperties()
+ && !rPPTShape.getTextBody()->hasListStyleOnImport()
+ && !rPPTShape.getTextBody()->hasParagraphProperties();
+}
+}
+
+oox::drawingml::TextListStylePtr PPTShape::getSubTypeTextListStyle( const SlidePersist& rSlidePersist, sal_Int32 nSubType )
+{
+ oox::drawingml::TextListStylePtr pTextListStyle;
+
+ SAL_INFO("oox.ppt", "subtype style: " << lclDebugSubType( nSubType ) );
+
+ switch( nSubType )
+ {
+ case XML_ctrTitle :
+ case XML_title :
+ pTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
+ break;
+ case XML_subTitle :
+ case XML_obj :
+ case XML_body :
+ if ( rSlidePersist.isNotesPage() )
+ pTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
+ else
+ pTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
+ break;
+ }
+
+ return pTextListStyle;
+}
+
+bool PPTShape::IsPlaceHolderCandidate(const SlidePersist& rSlidePersist) const
+{
+ if (meShapeLocation != Slide)
+ return false;
+ if (rSlidePersist.isNotesPage())
+ return false;
+ auto pTextBody = getTextBody();
+ if (!pTextBody)
+ return false;
+ auto rParagraphs = pTextBody->getParagraphs();
+ if (rParagraphs.size() != 1)
+ return false;
+ if (rParagraphs.front()->getRuns().size() != 1)
+ return false;
+ // If the placeholder has a shape other than rectangle,
+ // we have to place it in the slide as a CustomShape.
+ if (!mpCustomShapePropertiesPtr->representsDefaultShape())
+ return false;
+ return ShapeHasNoVisualPropertiesOnImport(*this);
+}
+
+void PPTShape::addShape(
+ oox::core::XmlFilterBase& rFilterBase,
+ const SlidePersist& rSlidePersist,
+ const oox::drawingml::Theme* pTheme,
+ const Reference< XShapes >& rxShapes,
+ basegfx::B2DHomMatrix& aTransformation,
+ ::oox::drawingml::ShapeIdMap* pShapeMap )
+{
+ SAL_INFO("oox.ppt","add shape id: " << msId << " location: " << ((meShapeLocation == Master) ? "master" : ((meShapeLocation == Slide) ? "slide" : ((meShapeLocation == Layout) ? "layout" : "other"))) << " subtype: " << mnSubType << " service: " << msServiceName);
+ // only placeholder from layout are being inserted
+ if ( mnSubType && ( meShapeLocation == Master ) )
+ return;
+
+ OUString sServiceName( msServiceName );
+ if (sServiceName.isEmpty())
+ return;
+ try
+ {
+ oox::drawingml::TextListStylePtr aMasterTextListStyle;
+ Reference<lang::XMultiServiceFactory> xServiceFact(rFilterBase.getModel(), UNO_QUERY_THROW);
+ bool bClearText = false;
+
+ if (sServiceName != "com.sun.star.drawing.GraphicObjectShape" &&
+ sServiceName != "com.sun.star.drawing.OLE2Shape")
+ {
+ static const OUStringLiteral sOutlinerShapeService(u"com.sun.star.presentation.OutlinerShape");
+ SAL_INFO("oox.ppt","has master: " << std::hex << rSlidePersist.getMasterPersist().get());
+ switch (mnSubType)
+ {
+ case XML_ctrTitle :
+ case XML_title :
+ {
+ sServiceName = "com.sun.star.presentation.TitleTextShape";
+ aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
+ }
+ break;
+ case XML_subTitle :
+ {
+ if ((meShapeLocation == Master) || (meShapeLocation == Layout))
+ sServiceName = OUString();
+ else {
+ sServiceName = "com.sun.star.presentation.SubtitleShape";
+ aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
+ }
+ }
+ break;
+ case XML_obj :
+ {
+ sServiceName = sOutlinerShapeService;
+ aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
+ }
+ break;
+ case XML_body :
+ {
+ if (rSlidePersist.isNotesPage())
+ {
+ sServiceName = "com.sun.star.presentation.NotesShape";
+ aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
+ }
+ else
+ {
+ sServiceName = sOutlinerShapeService;
+ aMasterTextListStyle = rSlidePersist.getMasterPersist() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
+ }
+ }
+ break;
+ case XML_dt :
+ if (IsPlaceHolderCandidate(rSlidePersist))
+ {
+ TextRunPtr& pTextRun = getTextBody()->getParagraphs().front()->getRuns().front();
+ oox::drawingml::TextField* pTextField = dynamic_cast<oox::drawingml::TextField*>(pTextRun.get());
+ if (pTextField)
+ {
+ OUString aType = pTextField->getType();
+ if ( aType.startsWith("datetime") )
+ {
+ SvxDateFormat eDateFormat = drawingml::TextField::getLODateFormat(aType);
+ SvxTimeFormat eTimeFormat = drawingml::TextField::getLOTimeFormat(aType);
+ Reference< XPropertySet > xPropertySet( rSlidePersist.getPage(), UNO_QUERY );
+
+ if( eDateFormat != SvxDateFormat::AppDefault
+ || eTimeFormat != SvxTimeFormat::AppDefault )
+ {
+ // DateTimeFormat property looks for the date in 4 LSBs
+ // and looks for time format in the 4 bits after that
+ sal_Int32 nDateTimeFormat = static_cast<sal_Int32>(eDateFormat) |
+ static_cast<sal_Int32>(eTimeFormat) << 4;
+ xPropertySet->setPropertyValue( "IsDateTimeVisible", Any(true) );
+ xPropertySet->setPropertyValue( "IsDateTimeFixed", Any(false) );
+ xPropertySet->setPropertyValue( "DateTimeFormat", Any(nDateTimeFormat) );
+ return;
+ }
+ }
+ }
+ }
+ sServiceName = "com.sun.star.presentation.DateTimeShape";
+ bClearText = true;
+ break;
+ case XML_hdr :
+ sServiceName = "com.sun.star.presentation.HeaderShape";
+ bClearText = true;
+ break;
+ case XML_ftr :
+ if (IsPlaceHolderCandidate(rSlidePersist))
+ {
+ const OUString& rFooterText = getTextBody()->toString();
+
+ if( !rFooterText.isEmpty() )
+ {
+ // if it is possible to get the footer as a property the LO way,
+ // get it and discard the shape
+ Reference< XPropertySet > xPropertySet( rSlidePersist.getPage(), UNO_QUERY );
+ xPropertySet->setPropertyValue( "IsFooterVisible", Any( true ) );
+ xPropertySet->setPropertyValue( "FooterText", Any(rFooterText) );
+ return;
+ }
+ }
+ sServiceName = "com.sun.star.presentation.FooterShape";
+ bClearText = true;
+ break;
+ case XML_sldNum :
+ if (IsPlaceHolderCandidate(rSlidePersist))
+ {
+ TextRunPtr& pTextRun
+ = getTextBody()->getParagraphs().front()->getRuns().front();
+ oox::drawingml::TextField* pTextField
+ = dynamic_cast<oox::drawingml::TextField*>(pTextRun.get());
+ if (pTextField && pTextField->getType() == "slidenum")
+ {
+ // if it is possible to get the slidenum placeholder as a property
+ // do that and discard the shape
+ Reference<XPropertySet> xPropertySet(rSlidePersist.getPage(),
+ UNO_QUERY);
+ xPropertySet->setPropertyValue("IsPageNumberVisible", Any(true));
+ return;
+ }
+ }
+ sServiceName = "com.sun.star.presentation.SlideNumberShape";
+ bClearText = true;
+ break;
+ case XML_sldImg :
+ sServiceName = "com.sun.star.presentation.PageShape";
+ break;
+ case XML_chart :
+ if (meShapeLocation == Layout)
+ sServiceName = sOutlinerShapeService;
+ else
+ sServiceName = "com.sun.star.presentation.ChartShape";
+ break;
+ case XML_tbl :
+ if (meShapeLocation == Layout)
+ sServiceName = sOutlinerShapeService;
+ else
+ sServiceName = "com.sun.star.presentation.TableShape";
+ break;
+ case XML_pic :
+ if (meShapeLocation == Layout)
+ sServiceName = sOutlinerShapeService;
+ else
+ sServiceName = "com.sun.star.presentation.GraphicObjectShape";
+ break;
+ case XML_media :
+ if (meShapeLocation == Layout)
+ sServiceName = sOutlinerShapeService;
+ else
+ sServiceName = "com.sun.star.presentation.MediaShape";
+ break;
+ default:
+ if (mnSubType && meShapeLocation == Layout)
+ sServiceName = sOutlinerShapeService;
+ break;
+ }
+ }
+
+ // Since it is not possible to represent custom shaped placeholders in Impress
+ // Need to use service name css.drawing.CustomShape if they have a non default shape.
+ // This workaround has the drawback of them not really being processed as placeholders
+ // so it is only done for slide footers...
+ if ((mnSubType == XML_sldNum || mnSubType == XML_dt || mnSubType == XML_ftr)
+ && meShapeLocation == Slide && !mpCustomShapePropertiesPtr->representsDefaultShape())
+ {
+ sServiceName = "com.sun.star.drawing.CustomShape";
+ }
+
+ SAL_INFO("oox.ppt","shape service: " << sServiceName);
+
+ if (mnSubType && getSubTypeIndex().has() && meShapeLocation == Layout)
+ {
+ oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex( getSubTypeIndex().get(), rSlidePersist.getShapes()->getChildren(), true );
+ if (!pPlaceholder)
+ pPlaceholder = PPTShape::findPlaceholder( mnSubType, 0, getSubTypeIndex(), rSlidePersist.getShapes()->getChildren(), true );
+
+ if (pPlaceholder) {
+ if (maSize.Width == 0 || maSize.Height == 0) {
+ awt::Size aSize = maSize;
+ if (maSize.Width == 0)
+ aSize.Width = pPlaceholder->getSize().Width;
+ if (maSize.Height == 0)
+ aSize.Height = pPlaceholder->getSize().Height;
+ setSize( aSize );
+ if (maPosition.X == 0 || maPosition.Y == 0) {
+ awt::Point aPosition = maPosition;
+ if (maPosition.X == 0)
+ aPosition.X = pPlaceholder->getPosition().X;
+ if (maPosition.Y == 0)
+ aPosition.Y = pPlaceholder->getPosition().Y;
+ setPosition( aPosition );
+ }
+ }
+ }
+ }
+
+ // use placeholder index if possible
+ if (mnSubType && getSubTypeIndex().has() && rSlidePersist.getMasterPersist())
+ {
+ oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex(getSubTypeIndex().get(), rSlidePersist.getMasterPersist()->getShapes()->getChildren());
+ // TODO: Check if this is required for non-notes slides as well...
+ if (rSlidePersist.isNotesPage() && pPlaceholder && pPlaceholder->getSubType() != getSubType())
+ pPlaceholder.reset();
+
+ if (pPlaceholder) {
+ SAL_INFO("oox.ppt","found placeholder with index: " << getSubTypeIndex().get() << " and type: " << lclDebugSubType( mnSubType ));
+ PPTShape* pPPTPlaceholder = dynamic_cast< PPTShape* >( pPlaceholder.get() );
+ TextListStylePtr pNewTextListStyle = std::make_shared<TextListStyle>();
+
+ if (pPlaceholder->getTextBody()) {
+
+ pNewTextListStyle->apply( pPlaceholder->getTextBody()->getTextListStyle() );
+ if (pPlaceholder->getMasterTextListStyle())
+ pNewTextListStyle->apply( *pPlaceholder->getMasterTextListStyle() );
+
+ // SAL_INFO("oox.ppt","placeholder body style");
+ // pPlaceholder->getTextBody()->getTextListStyle().dump();
+ // SAL_INFO("oox.ppt","master text list style");
+ // pPlaceholder->getMasterTextListStyle()->dump();
+
+ aMasterTextListStyle = pNewTextListStyle;
+ // SAL_INFO("oox.ppt","combined master text list style");
+ // aMasterTextListStyle->dump();
+ }
+ if (pPPTPlaceholder && pPPTPlaceholder->mpPlaceholder) {
+ SAL_INFO("oox.ppt","placeholder has parent placeholder: " << pPPTPlaceholder->mpPlaceholder->getId() << " type: " << lclDebugSubType( pPPTPlaceholder->mpPlaceholder->getSubType() ) << " index: " << pPPTPlaceholder->mpPlaceholder->getSubTypeIndex().get() );
+ SAL_INFO("oox.ppt","has textbody " << (pPPTPlaceholder->mpPlaceholder->getTextBody() != nullptr) );
+ TextListStylePtr pPlaceholderStyle = getSubTypeTextListStyle( rSlidePersist, pPPTPlaceholder->mpPlaceholder->getSubType() );
+ if (pPPTPlaceholder->mpPlaceholder->getTextBody())
+ pNewTextListStyle->apply( pPPTPlaceholder->mpPlaceholder->getTextBody()->getTextListStyle() );
+ if (pPlaceholderStyle) {
+ pNewTextListStyle->apply( *pPlaceholderStyle );
+ //pPlaceholderStyle->dump();
+ }
+ }
+ } else if (!mpPlaceholder) {
+ aMasterTextListStyle.reset();
+ }
+ SAL_INFO("oox.ppt","placeholder id: " << (pPlaceholder ? pPlaceholder->getId() : "not found"));
+ }
+
+ if (!sServiceName.isEmpty())
+ {
+ if (!aMasterTextListStyle)
+ {
+ bool isOther = !getTextBody() && sServiceName != "com.sun.star.drawing.GroupShape";
+ TextListStylePtr aSlideStyle = isOther ? rSlidePersist.getOtherTextStyle() : rSlidePersist.getDefaultTextStyle();
+ // Combine from MasterSlide details as well.
+ if (rSlidePersist.getMasterPersist())
+ {
+ aMasterTextListStyle = isOther ? rSlidePersist.getMasterPersist()->getOtherTextStyle() : rSlidePersist.getMasterPersist()->getDefaultTextStyle();
+ if (aSlideStyle)
+ aMasterTextListStyle->apply( *aSlideStyle );
+ }
+ else
+ {
+ aMasterTextListStyle = aSlideStyle;
+ }
+ }
+
+ if( aMasterTextListStyle && getTextBody() ) {
+ TextListStylePtr aCombinedTextListStyle = std::make_shared<TextListStyle>();
+
+ aCombinedTextListStyle->apply( *aMasterTextListStyle );
+
+ if( mpPlaceholder && mpPlaceholder->getTextBody() )
+ aCombinedTextListStyle->apply( mpPlaceholder->getTextBody()->getTextListStyle() );
+ aCombinedTextListStyle->apply( getTextBody()->getTextListStyle() );
+
+ setMasterTextListStyle( aCombinedTextListStyle );
+ } else
+ setMasterTextListStyle( aMasterTextListStyle );
+
+ Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, bClearText, bool(mpPlaceholder), aTransformation, getFillProperties() ) );
+ // if exists and not duplicated, try to use the title text as slide name to help its re-use on UI
+ if (!rSlidePersist.isMasterPage() && rSlidePersist.getPage().is() && (mnSubType == XML_title || mnSubType == XML_ctrTitle))
+ {
+ try
+ {
+ sal_Int32 nCount = 1;
+ OUString aTitleText;
+ Reference<XTextRange> xText(xShape, UNO_QUERY_THROW);
+ aTitleText = xText->getString();
+ Reference<drawing::XDrawPagesSupplier> xDPS(rFilterBase.getModel(), uno::UNO_QUERY_THROW);
+ Reference<drawing::XDrawPages> xDrawPages(xDPS->getDrawPages(), uno::UNO_SET_THROW);
+ sal_uInt32 nMaxPages = xDrawPages->getCount();
+ // just a magic value but we don't want to drop out slide names which are too long
+ if (aTitleText.getLength() > 63)
+ aTitleText = aTitleText.copy(0, 63);
+ bool bUseTitleAsSlideName = !aTitleText.isEmpty();
+ // check duplicated title name
+ if (bUseTitleAsSlideName)
+ {
+ for (sal_uInt32 nPage = 0; nPage < nMaxPages; ++nPage)
+ {
+ Reference<XDrawPage> xDrawPage(xDrawPages->getByIndex(nPage), uno::UNO_QUERY);
+ Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
+ OUString sRest;
+ if (xNamed->getName().startsWith(aTitleText, &sRest)
+ && (sRest.isEmpty()
+ || (sRest.startsWith(" (") && sRest.endsWith(")")
+ && o3tl::toInt32(sRest.subView(2, sRest.getLength() - 3)) > 0)))
+ nCount++;
+ }
+ Reference<container::XNamed> xName(rSlidePersist.getPage(), UNO_QUERY_THROW);
+ xName->setName(
+ aTitleText
+ + (nCount == 1 ? OUString("") : " (" + OUString::number(nCount) + ")"));
+ }
+ }
+ catch (uno::Exception&)
+ {
+
+ }
+ }
+
+ // Apply text properties on placeholder text inside this placeholder shape
+ if (meShapeLocation == Slide && mpPlaceholder && getTextBody() && getTextBody()->isEmpty())
+ {
+ Reference < XText > xText(mxShape, UNO_QUERY);
+ if (xText.is())
+ {
+ TextCharacterProperties aCharStyleProperties;
+ getTextBody()->ApplyStyleEmpty(rFilterBase, xText, aCharStyleProperties, mpMasterTextListStyle);
+ }
+ }
+ if (pShapeMap)
+ {
+ // bnc#705982 - if optional model id reference is
+ // there, use that to obtain target shape
+ if (!msModelId.isEmpty())
+ {
+ (*pShapeMap)[ msModelId ] = shared_from_this();
+ }
+ else if (!msId.isEmpty())
+ {
+ (*pShapeMap)[ msId ] = shared_from_this();
+ }
+ }
+
+ // we will be losing whatever information there is in the footer placeholder on master/layout slides
+ // since they should have the "<footer>" textfield in them in order to make LibreOffice process them as expected
+ // likewise DateTime placeholder data on master/layout slides will be lost and replaced
+ if( (mnSubType == XML_ftr || mnSubType == XML_dt) && meShapeLocation != Slide )
+ {
+ OUString aFieldType;
+ if( mnSubType == XML_ftr )
+ aFieldType = "com.sun.star.presentation.TextField.Footer";
+ else
+ aFieldType = "com.sun.star.presentation.TextField.DateTime";
+ Reference < XTextField > xField( xServiceFact->createInstance( aFieldType ), UNO_QUERY );
+ Reference < XText > xText(mxShape, UNO_QUERY);
+ if(xText.is())
+ {
+ xText->setString("");
+ Reference < XTextCursor > xTextCursor = xText->createTextCursor();
+ xText->insertTextContent( xTextCursor, xField, false);
+ }
+ }
+
+ OUString sURL;
+ std::vector<std::pair<OUString, Reference<XShape>>> aURLShapes;
+ // if this is a group shape, we have to add also each child shape
+ Reference<XShapes> xShapes(xShape, UNO_QUERY);
+ if (xShapes.is())
+ {
+ // temporarily remember setting
+ NamedShapePairs* pDiagramFontHeights(rFilterBase.getDiagramFontHeights());
+
+ // for shapes unequal to FRAMETYPE_DIAGRAM do
+ // disable DiagramFontHeights recording
+ if (meFrameType != FRAMETYPE_DIAGRAM)
+ rFilterBase.setDiagramFontHeights(nullptr);
+
+ addChildren( rFilterBase, *this, pTheme, xShapes, pShapeMap, aTransformation );
+
+ // restore remembered setting
+ rFilterBase.setDiagramFontHeights(pDiagramFontHeights);
+
+ for (size_t i = 0; i < this->getChildren().size(); i++)
+ {
+ this->getChildren()[i]->getShapeProperties().getProperty(PROP_URL) >>= sURL;
+ if (!sURL.isEmpty())
+ {
+ Reference<XShape> xChild = this->getChildren()[i]->getXShape();
+ aURLShapes.push_back({ sURL, xChild });
+ }
+ }
+ }
+
+ if (meFrameType == FRAMETYPE_DIAGRAM)
+ {
+ keepDiagramCompatibilityInfo();
+ }
+
+ // Support advanced DiagramHelper
+ if (FRAMETYPE_DIAGRAM == meFrameType)
+ {
+ propagateDiagramHelper();
+ }
+
+ getShapeProperties().getProperty(PROP_URL) >>= sURL;
+ if (!sURL.isEmpty() && !xShapes.is())
+ aURLShapes.push_back({ sURL, xShape });
+
+ if (!aURLShapes.empty())
+ {
+ for (auto const& URLShape : aURLShapes)
+ {
+ Reference<XEventsSupplier> xEventsSupplier(URLShape.second, UNO_QUERY);
+ if (!xEventsSupplier.is())
+ return;
+
+ Reference<XNameReplace> xEvents(xEventsSupplier->getEvents());
+ if (!xEvents.is())
+ return;
+
+ OUString sAPIEventName;
+ sal_Int32 nPropertyCount = 2;
+ css::presentation::ClickAction meClickAction;
+ uno::Sequence<beans::PropertyValue> aProperties;
+
+ std::map<OUString, css::presentation::ClickAction> ActionMap = {
+ { "#action?jump=nextslide", ClickAction_NEXTPAGE },
+ { "#action?jump=previousslide", ClickAction_PREVPAGE },
+ { "#action?jump=firstslide", ClickAction_FIRSTPAGE },
+ { "#action?jump=lastslide", ClickAction_LASTPAGE },
+ { "#action?jump=endshow", ClickAction_STOPPRESENTATION },
+ };
+
+ sURL = URLShape.first;
+ std::map<OUString, css::presentation::ClickAction>::const_iterator aIt
+ = ActionMap.find(sURL);
+ aIt != ActionMap.end() ? meClickAction = aIt->second
+ : meClickAction = ClickAction_BOOKMARK;
+
+ // ClickAction_BOOKMARK and ClickAction_DOCUMENT share the same event
+ // so check here if it's a bookmark or a document
+ if (meClickAction == ClickAction_BOOKMARK)
+ {
+ sal_Int32 nSplitPos;
+ if (!sURL.startsWith("#"))
+ meClickAction = ClickAction_DOCUMENT;
+ else if (-1 != (nSplitPos = sURL.indexOf( ' ' )))
+ {
+ setBookmark(true);
+ // reuse slide number from '#Slide [Num]' or "#Notes [Num]"
+ sURL = OUString::Concat("#page") + sURL.subView(nSplitPos);
+ }
+ nPropertyCount += 1;
+ }
+
+ aProperties.realloc(nPropertyCount);
+ beans::PropertyValue* pProperties = aProperties.getArray();
+
+ pProperties->Name = "EventType";
+ pProperties->Handle = -1;
+ pProperties->Value <<= OUString("Presentation");
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ pProperties->Name = "ClickAction";
+ pProperties->Handle = -1;
+ pProperties->Value <<= meClickAction;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ pProperties++;
+
+ switch (meClickAction)
+ {
+ case ClickAction_BOOKMARK:
+ case ClickAction_DOCUMENT:
+ pProperties->Name = "Bookmark";
+ pProperties->Handle = -1;
+ pProperties->Value <<= sURL;
+ pProperties->State = beans::PropertyState_DIRECT_VALUE;
+ break;
+ default:
+ break;
+ }
+
+ sAPIEventName = "OnClick";
+ xEvents->replaceByName(sAPIEventName, uno::Any(aProperties));
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+namespace
+{
+ bool ShapeLocationIsMaster(oox::drawingml::Shape *pInShape)
+ {
+ PPTShape* pShape = dynamic_cast<PPTShape*>(pInShape);
+ return pShape && pShape->getShapeLocation() == Master;
+ }
+}
+
+// Function to find placeholder (ph) for a shape. No idea how MSO implements this, but
+// this order seems to work quite well
+// (probably it's unnecessary complicated / wrong. i.e. tdf#104202):
+// 1. ph with nFirstSubType and the same oSubTypeIndex
+// 2. ph with nFirstSubType
+// 3. ph with nSecondSubType and the same oSubTypeIndex
+// 4. ph with nSecondSubType
+// 5. ph with the same oSubTypeIndex
+
+oox::drawingml::ShapePtr PPTShape::findPlaceholder( sal_Int32 nFirstSubType, sal_Int32 nSecondSubType,
+ const OptValue< sal_Int32 >& oSubTypeIndex, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
+{
+ class Placeholders
+ {
+ public:
+ Placeholders()
+ : aChoice(5) // resize to 5
+ {
+ }
+
+ void add(const oox::drawingml::ShapePtr& aShape, sal_Int32 nFirstSubType, sal_Int32 nSecondSubType, const OptValue< sal_Int32 >& oSubTypeIndex)
+ {
+ if (!aShape)
+ return;
+
+ // get flags
+ const bool bSameFirstSubType = aShape->getSubType() == nFirstSubType;
+ const bool bSameSecondSubType = aShape->getSubType() == nSecondSubType;
+ const bool bSameIndex = aShape->getSubTypeIndex() == oSubTypeIndex;
+
+ // get prio
+ int aPrioIndex = -1;
+ if (bSameIndex && bSameFirstSubType)
+ aPrioIndex = 0;
+ else if (!bSameIndex && bSameFirstSubType)
+ aPrioIndex = 1;
+ else if (bSameIndex && bSameSecondSubType)
+ aPrioIndex = 2;
+ else if (!bSameIndex && bSameSecondSubType)
+ aPrioIndex = 3;
+ else if (bSameIndex)
+ aPrioIndex = 4;
+
+ // add
+ if (aPrioIndex != -1)
+ {
+ if (!aChoice.at(aPrioIndex))
+ {
+ aChoice.at(aPrioIndex) = aShape;
+ }
+ }
+ }
+
+ // return according to prio
+ oox::drawingml::ShapePtr getByPrio() const
+ {
+ for (const oox::drawingml::ShapePtr& aShape : aChoice)
+ {
+ if (aShape)
+ {
+ return aShape;
+ }
+ }
+
+ return oox::drawingml::ShapePtr();
+ }
+
+ bool hasByPrio(size_t aIndex) const
+ {
+ return bool(aChoice.at(aIndex));
+ }
+
+ private:
+ std::vector< oox::drawingml::ShapePtr > aChoice;
+
+ } aPlaceholders;
+
+ // check all shapes
+ std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
+ for (; aRevIter != rShapes.rend(); ++aRevIter)
+ {
+ // check shape
+ if (!bMasterOnly || ShapeLocationIsMaster((*aRevIter).get()))
+ {
+ const oox::drawingml::ShapePtr& aShape = *aRevIter;
+ aPlaceholders.add(aShape, nFirstSubType, nSecondSubType, oSubTypeIndex);
+ }
+
+ // check children
+ std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
+ if (!rChildren.empty())
+ {
+ const oox::drawingml::ShapePtr aShape = findPlaceholder( nFirstSubType, nSecondSubType, oSubTypeIndex, rChildren, bMasterOnly );
+ if (aShape)
+ {
+ aPlaceholders.add(aShape, nFirstSubType, nSecondSubType, oSubTypeIndex);
+ }
+ }
+
+ if (aPlaceholders.hasByPrio(0))
+ {
+ break;
+ }
+ }
+
+ // return something according to prio
+ return aPlaceholders.getByPrio();
+}
+
+oox::drawingml::ShapePtr PPTShape::findPlaceholderByIndex( const sal_Int32 nIdx, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
+{
+ oox::drawingml::ShapePtr aShapePtr;
+
+ std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
+ while( aRevIter != rShapes.rend() )
+ {
+ if ( (*aRevIter)->getSubTypeIndex().has() && (*aRevIter)->getSubTypeIndex().get() == nIdx &&
+ ( !bMasterOnly || ShapeLocationIsMaster((*aRevIter).get()) ) )
+ {
+ aShapePtr = *aRevIter;
+ break;
+ }
+ std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
+ aShapePtr = findPlaceholderByIndex( nIdx, rChildren, bMasterOnly );
+ if ( aShapePtr )
+ break;
+ ++aRevIter;
+ }
+ return aShapePtr;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptshapecontext.cxx b/oox/source/ppt/pptshapecontext.cxx
new file mode 100644
index 000000000..d7f3d90f2
--- /dev/null
+++ b/oox/source/ppt/pptshapecontext.cxx
@@ -0,0 +1,195 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/log.hxx>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/ppt/pptshape.hxx>
+#include <oox/ppt/pptshapecontext.hxx>
+#include <oox/ppt/pptshapepropertiescontext.hxx>
+#include <oox/ppt/slidepersist.hxx>
+#include <drawingml/shapestylecontext.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <drawingml/textbodycontext.hxx>
+#include <drawingml/transform2dcontext.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/properties.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::text;
+
+namespace oox::ppt {
+
+// CT_Shape
+PPTShapeContext::PPTShapeContext( ContextHandler2Helper const & rParent, const SlidePersistPtr& rSlidePersistPtr, const oox::drawingml::ShapePtr& pMasterShapePtr, const oox::drawingml::ShapePtr& pShapePtr )
+: oox::drawingml::ShapeContext( rParent, pMasterShapePtr, pShapePtr )
+, mpSlidePersistPtr( rSlidePersistPtr )
+{
+}
+
+ContextHandlerRef PPTShapeContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ if( getNamespace( aElementToken ) == NMSP_dsp )
+ aElementToken = NMSP_ppt | getBaseToken( aElementToken );
+
+ switch( aElementToken )
+ {
+ // nvSpPr CT_ShapeNonVisual begin
+ // case PPT_TOKEN( drElemPr ):
+ // break;
+ case PPT_TOKEN( cNvPr ):
+ {
+ mpShapePtr->setHidden( rAttribs.getBool( XML_hidden, false ) );
+ mpShapePtr->setId( rAttribs.getString( XML_id ).get() );
+ mpShapePtr->setName( rAttribs.getString( XML_name ).get() );
+ break;
+ }
+ case PPT_TOKEN( ph ):
+ {
+ SlidePersistPtr pMasterPersist( mpSlidePersistPtr->getMasterPersist() );
+ OptValue< sal_Int32 > oSubType( rAttribs.getToken( XML_type) );
+ sal_Int32 nSubType( rAttribs.getToken( XML_type, XML_obj ) );
+ oox::drawingml::ShapePtr pTmpPlaceholder;
+
+ mpShapePtr->setSubType( nSubType );
+
+ if( rAttribs.hasAttribute( XML_idx ) )
+ {
+ sal_Int32 nSubTypeIndex = rAttribs.getString( XML_idx ).get().toInt32();
+ mpShapePtr->setSubTypeIndex( nSubTypeIndex );
+
+ if(!oSubType.has() && pMasterPersist)
+ {
+ pTmpPlaceholder = PPTShape::findPlaceholderByIndex( nSubTypeIndex, pMasterPersist->getShapes()->getChildren() );
+
+ if(pTmpPlaceholder)
+ nSubType = pTmpPlaceholder->getSubType(); // When we don't have type attribute on slide but have on slidelayout we have to use it instead of default type
+ }
+ }
+
+ if ( nSubType )
+ {
+ PPTShape* pPPTShapePtr = dynamic_cast< PPTShape* >( mpShapePtr.get() );
+ if ( pPPTShapePtr )
+ {
+ oox::ppt::ShapeLocation eShapeLocation = pPPTShapePtr->getShapeLocation();
+ if ( ( eShapeLocation == Slide ) || ( eShapeLocation == Layout ) )
+ {
+ // inheriting properties from placeholder objects by cloning shape
+ sal_Int32 nFirstPlaceholder = 0;
+ sal_Int32 nSecondPlaceholder = 0;
+ switch( nSubType )
+ {
+ case XML_ctrTitle : // slide/layout
+ nFirstPlaceholder = XML_ctrTitle;
+ nSecondPlaceholder = XML_title;
+ break;
+
+ case XML_subTitle : // slide/layout
+ nFirstPlaceholder = XML_subTitle;
+ nSecondPlaceholder = XML_body;
+ break;
+
+ case XML_obj : // slide/layout
+ nFirstPlaceholder = XML_obj;
+ nSecondPlaceholder = XML_body;
+ break;
+
+ case XML_dt : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_sldNum : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_ftr : // slide/layout/master/notes/notesmaster/handoutmaster
+ case XML_hdr : // notes/notesmaster/handoutmaster
+ case XML_body : // slide/layout/master/notes/notesmaster
+ case XML_title : // slide/layout/master/
+ case XML_chart : // slide/layout
+ case XML_tbl : // slide/layout
+ case XML_clipArt : // slide/layout
+ case XML_dgm : // slide/layout
+ case XML_media : // slide/layout
+ case XML_sldImg : // notes/notesmaster
+ case XML_pic : // slide/layout
+ nFirstPlaceholder = nSubType;
+ break;
+ default:
+ break;
+ }
+ if ( nFirstPlaceholder )
+ {
+ oox::drawingml::ShapePtr pPlaceholder;
+ if ( eShapeLocation == Layout ) // for layout objects the referenced object can be found within the same shape tree
+ {
+ pPlaceholder = PPTShape::findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
+ pPPTShapePtr->getSubTypeIndex(), mpSlidePersistPtr->getShapes()->getChildren(), true );
+ }
+ else if ( eShapeLocation == Slide ) // normal slide shapes have to search within the corresponding master tree for referenced objects
+ {
+ if ( pMasterPersist )
+ {
+ pPlaceholder = PPTShape::findPlaceholder( nFirstPlaceholder, nSecondPlaceholder,
+ pPPTShapePtr->getSubTypeIndex(), pMasterPersist->getShapes()->getChildren() );
+ }
+ }
+ if ( pPlaceholder )
+ {
+ SAL_INFO("oox.ppt","shape " << mpShapePtr->getId() <<
+ " will get shape reference " << pPlaceholder->getId() << " applied");
+ mpShapePtr->applyShapeReference( *pPlaceholder );
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( pPlaceholder.get() );
+ if ( pPPTShape )
+ pPPTShape->setReferenced( true );
+ pPPTShapePtr->setPlaceholder( pPlaceholder );
+ }
+ }
+ }
+ }
+
+ }
+ break;
+ }
+
+ // nvSpPr CT_ShapeNonVisual end
+
+ case PPT_TOKEN( spPr ):
+ return new PPTShapePropertiesContext( *this, *mpShapePtr );
+
+ case PPT_TOKEN( style ):
+ return new oox::drawingml::ShapeStyleContext( *this, *mpShapePtr );
+
+ case PPT_TOKEN( txBody ):
+ {
+ oox::drawingml::TextBodyPtr xTextBody = std::make_shared<oox::drawingml::TextBody>( mpShapePtr->getTextBody() );
+ xTextBody->getTextProperties().maPropertyMap.setProperty( PROP_FontIndependentLineSpacing, true );
+ mpShapePtr->setTextBody( xTextBody );
+ return new oox::drawingml::TextBodyContext( *this, mpShapePtr );
+ }
+ case PPT_TOKEN( txXfrm ):
+ {
+ return new oox::drawingml::Transform2DContext( *this, rAttribs, *mpShapePtr, true );
+ }
+ }
+
+ return ShapeContext::onCreateContext(aElementToken, rAttribs);
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptshapegroupcontext.cxx b/oox/source/ppt/pptshapegroupcontext.cxx
new file mode 100644
index 000000000..17d3e6c58
--- /dev/null
+++ b/oox/source/ppt/pptshapegroupcontext.cxx
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <com/sun/star/xml/sax/FastToken.hpp>
+
+#include <oox/core/xmlfilterbase.hxx>
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/ppt/pptshape.hxx>
+#include <oox/ppt/pptgraphicshapecontext.hxx>
+#include <oox/ppt/pptshapecontext.hxx>
+#include <oox/ppt/pptshapegroupcontext.hxx>
+#include <oox/drawingml/graphicshapecontext.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <drawingml/shapepropertiescontext.hxx>
+#include <oox/drawingml/connectorshapecontext.hxx>
+#include <drawingml/fillproperties.hxx>
+#include "extdrawingfragmenthandler.hxx"
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::text;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+PPTShapeGroupContext::PPTShapeGroupContext(
+ FragmentHandler2 const & rParent,
+ const oox::ppt::SlidePersistPtr& rSlidePersistPtr,
+ const ShapeLocation eShapeLocation,
+ const oox::drawingml::ShapePtr& pMasterShapePtr,
+ const oox::drawingml::ShapePtr& pGroupShapePtr )
+: ShapeGroupContext( rParent, pMasterShapePtr, pGroupShapePtr )
+, mpSlidePersistPtr( rSlidePersistPtr )
+, meShapeLocation( eShapeLocation )
+{
+}
+
+ContextHandlerRef PPTShapeGroupContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ if( getNamespace( aElementToken ) == NMSP_dsp )
+ aElementToken = NMSP_ppt | getBaseToken( aElementToken );
+
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( cNvPr ):
+ {
+ // don't override SmartArt properties for embedded drawing's spTree
+ mpGroupShapePtr->setHidden( rAttribs.getBool( XML_hidden, false ) );
+ if (mpGroupShapePtr->getId().isEmpty())
+ mpGroupShapePtr->setId(rAttribs.getString(XML_id).get());
+ if (mpGroupShapePtr->getName().isEmpty())
+ mpGroupShapePtr->setName( rAttribs.getString( XML_name ).get() );
+ break;
+ }
+ case PPT_TOKEN( ph ):
+ mpGroupShapePtr->setSubType( rAttribs.getToken( XML_type, FastToken::DONTKNOW ) );
+ if( rAttribs.hasAttribute( XML_idx ) )
+ mpGroupShapePtr->setSubTypeIndex( rAttribs.getString( XML_idx ).get().toInt32() );
+ break;
+ // nvSpPr CT_ShapeNonVisual end
+
+ case PPT_TOKEN( grpSpPr ):
+ return new oox::drawingml::ShapePropertiesContext( *this, *mpGroupShapePtr );
+ case PPT_TOKEN( spPr ):
+ return new oox::drawingml::ShapePropertiesContext( *this, *mpGroupShapePtr );
+/*
+ case PPT_TOKEN( style ):
+ return new ShapeStyleContext( getParser() );
+*/
+ case PPT_TOKEN( cxnSp ): // connector shape
+ {
+ auto pShape = std::make_shared<PPTShape>(meShapeLocation, "com.sun.star.drawing.ConnectorShape");
+ return new oox::drawingml::ConnectorShapeContext(*this, mpGroupShapePtr, pShape,
+ pShape->getConnectorShapeProperties());
+ }
+ case PPT_TOKEN( grpSp ): // group shape
+ return new PPTShapeGroupContext( *this, mpSlidePersistPtr, meShapeLocation, mpGroupShapePtr, std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.GroupShape" ) );
+ case PPT_TOKEN( sp ): // Shape
+ {
+ auto pShape = std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.CustomShape" );
+ bool bUseBgFill = rAttribs.getBool(XML_useBgFill, false);
+ if (bUseBgFill)
+ {
+ pShape->getFillProperties().moFillType = XML_noFill;
+ pShape->getFillProperties().moUseBgFill = true;
+ }
+ pShape->setModelId(rAttribs.getString( XML_modelId ).get());
+ return new PPTShapeContext( *this, mpSlidePersistPtr, mpGroupShapePtr, pShape );
+ }
+ case PPT_TOKEN( pic ): // CT_Picture
+ return new PPTGraphicShapeContext( *this, mpSlidePersistPtr, mpGroupShapePtr, std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.GraphicObjectShape" ) );
+ case PPT_TOKEN( graphicFrame ): // CT_GraphicalObjectFrame
+ {
+ pGraphicShape = std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.OLE2Shape" );
+ return new oox::drawingml::GraphicalObjectFrameContext( *this, mpGroupShapePtr, pGraphicShape, true );
+ }
+ }
+
+ return this;
+}
+
+void PPTShapeGroupContext::importExtDrawings( )
+{
+ if( !pGraphicShape )
+ return;
+
+ for (auto const& extDrawing : pGraphicShape->getExtDrawings())
+ {
+ OUString aFragmentPath = getFragmentPathFromRelId(extDrawing);
+ getFilter().importFragment( new ExtDrawingFragmentHandler( getFilter(), aFragmentPath,
+ mpSlidePersistPtr,
+ meShapeLocation,
+ mpGroupShapePtr,
+ pGraphicShape ) );
+ pGraphicShape->keepDiagramDrawing(getFilter(), aFragmentPath);
+
+ // Apply font color imported from color fragment
+ if( pGraphicShape->getFontRefColorForNodes().isUsed() )
+ applyFontRefColor(mpGroupShapePtr, pGraphicShape->getFontRefColorForNodes());
+ }
+ pGraphicShape = oox::drawingml::ShapePtr( nullptr );
+}
+
+void PPTShapeGroupContext::applyFontRefColor(const oox::drawingml::ShapePtr& pShape, const oox::drawingml::Color& rFontRefColor)
+{
+ pShape->getShapeStyleRefs()[XML_fontRef].maPhClr = rFontRefColor;
+ std::vector< oox::drawingml::ShapePtr >& vChildren = pShape->getChildren();
+ for (auto const& child : vChildren)
+ {
+ applyFontRefColor(child, rFontRefColor);
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/pptshapepropertiescontext.cxx b/oox/source/ppt/pptshapepropertiescontext.cxx
new file mode 100644
index 000000000..70ef2fcef
--- /dev/null
+++ b/oox/source/ppt/pptshapepropertiescontext.cxx
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/pptshapepropertiescontext.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/properties.hxx>
+#include <oox/ppt/pptshape.hxx>
+
+using namespace oox::core;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace oox::ppt {
+
+// CT_Shape
+PPTShapePropertiesContext::PPTShapePropertiesContext( ContextHandler2Helper const & rParent, ::oox::drawingml::Shape& rShape )
+: ShapePropertiesContext( rParent, rShape )
+{
+}
+
+ContextHandlerRef PPTShapePropertiesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ PPTShape* pPPTShape = dynamic_cast<PPTShape*>(&mrShape);
+ if (pPPTShape)
+ pPPTShape->setHasNoninheritedShapeProperties();
+
+ switch( aElementToken )
+ {
+ case A_TOKEN( xfrm ):
+ mrShape.getShapeProperties().setProperty( PROP_IsPlaceholderDependent, false);
+ return ShapePropertiesContext::onCreateContext( aElementToken, rAttribs );
+
+ default:
+ return ShapePropertiesContext::onCreateContext( aElementToken, rAttribs );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/presPropsfragmenthandler.cxx b/oox/source/ppt/presPropsfragmenthandler.cxx
new file mode 100644
index 000000000..4792d07c0
--- /dev/null
+++ b/oox/source/ppt/presPropsfragmenthandler.cxx
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/presentation/XPresentationSupplier.hpp>
+#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+
+#include <oox/core/xmlfilterbase.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/ppt/presPropsfragmenthandler.hxx>
+#include <oox/token/namespaces.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace oox::ppt
+{
+PresPropsFragmentHandler::PresPropsFragmentHandler(core::XmlFilterBase& rFilter,
+ const OUString& rFragmentPath)
+ : FragmentHandler2(rFilter, rFragmentPath)
+{
+}
+
+PresPropsFragmentHandler::~PresPropsFragmentHandler() = default;
+
+void PresPropsFragmentHandler::finalizeImport()
+{
+ css::uno::Reference<css::presentation::XPresentationSupplier> xPresentationSupplier(
+ getFilter().getModel(), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::beans::XPropertySet> xPresentationProps(
+ xPresentationSupplier->getPresentation(), css::uno::UNO_QUERY_THROW);
+ xPresentationProps->setPropertyValue("IsEndless", css::uno::Any(m_bLoop));
+ xPresentationProps->setPropertyValue("IsAutomatic", css::uno::Any(!m_bTiming));
+
+ if (!m_sId.isEmpty())
+ {
+ css::uno::Reference<css::presentation::XCustomPresentationSupplier>
+ XCustPresentationSupplier(getFilter().getModel(), css::uno::UNO_QUERY_THROW);
+ css::uno::Reference<css::container::XNameContainer> mxCustShows;
+ mxCustShows = XCustPresentationSupplier->getCustomPresentations();
+ const css::uno::Sequence<OUString> aNameSeq(mxCustShows->getElementNames());
+ xPresentationProps->setPropertyValue("CustomShow",
+ css::uno::Any(aNameSeq[m_sId.toInt32()]));
+ }
+
+ if (!m_sSt.isEmpty())
+ {
+ Reference<drawing::XDrawPagesSupplier> xDPS(getFilter().getModel(), uno::UNO_QUERY_THROW);
+ Reference<drawing::XDrawPages> xDrawPages(xDPS->getDrawPages(), uno::UNO_SET_THROW);
+ Reference<drawing::XDrawPage> xDrawPage;
+ xDrawPages->getByIndex(m_sSt.toInt32() - 1) >>= xDrawPage;
+ Reference<container::XNamed> xNamed(xDrawPage, uno::UNO_QUERY_THROW);
+ xPresentationProps->setPropertyValue("FirstPage", uno::Any(xNamed->getName()));
+ }
+}
+
+core::ContextHandlerRef PresPropsFragmentHandler::onCreateContext(sal_Int32 aElementToken,
+ const AttributeList& rAttribs)
+{
+ switch (aElementToken)
+ {
+ case PPT_TOKEN(presentationPr):
+ return this;
+ case PPT_TOKEN(showPr):
+ m_bLoop = rAttribs.getBool(XML_loop, false);
+ m_bTiming = rAttribs.getBool(XML_useTimings, true);
+ return this;
+ case PPT_TOKEN(custShow):
+ m_sId = rAttribs.getString(XML_id).get();
+ return this;
+ case PPT_TOKEN(sldRg):
+ m_sSt = rAttribs.getString(XML_st).get();
+ return this;
+ }
+ return this;
+}
+} // namespace oox::ppt
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/oox/source/ppt/presentationfragmenthandler.cxx b/oox/source/ppt/presentationfragmenthandler.cxx
new file mode 100644
index 000000000..ac1e32e53
--- /dev/null
+++ b/oox/source/ppt/presentationfragmenthandler.cxx
@@ -0,0 +1,792 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/anytostring.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <o3tl/string_view.hxx>
+#include <sal/log.hxx>
+#include <tools/multisel.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XMasterPagesSupplier.hpp>
+#include <com/sun/star/drawing/XDrawPages.hpp>
+#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
+#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/text/XTextField.hpp>
+#include <com/sun/star/xml/dom/XDocument.hpp>
+#include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
+#include <com/sun/star/presentation/XPresentationPage.hpp>
+#include <com/sun/star/task/XStatusIndicator.hpp>
+#include <com/sun/star/presentation/XCustomPresentationSupplier.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+
+#include <oox/drawingml/theme.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <oox/drawingml/themefragmenthandler.hxx>
+#include <drawingml/textliststylecontext.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/ole/olestorage.hxx>
+#include <oox/ole/vbaproject.hxx>
+#include <oox/ppt/pptshape.hxx>
+#include <oox/ppt/presentationfragmenthandler.hxx>
+#include <oox/ppt/slidefragmenthandler.hxx>
+#include <oox/ppt/layoutfragmenthandler.hxx>
+#include <oox/ppt/pptimport.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+#include <com/sun/star/office/XAnnotation.hpp>
+#include <com/sun/star/office/XAnnotationAccess.hpp>
+#include <ooxresid.hxx>
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+static std::map<PredefinedClrSchemeId, sal_Int32> PredefinedClrTokens =
+{
+ //{ dk1, XML_dk1 },
+ //{ lt1, XML_lt1 },
+ { dk2, XML_dk2 },
+ { lt2, XML_lt2 },
+ { accent1, XML_accent1 },
+ { accent2, XML_accent2 },
+ { accent3, XML_accent3 },
+ { accent4, XML_accent4 },
+ { accent5, XML_accent5 },
+ { accent6, XML_accent6 },
+ { hlink, XML_hlink },
+ { folHlink, XML_folHlink }
+};
+
+PresentationFragmentHandler::PresentationFragmentHandler(XmlFilterBase& rFilter, const OUString& rFragmentPath)
+ : FragmentHandler2( rFilter, rFragmentPath )
+ , mpTextListStyle( std::make_shared<TextListStyle>() )
+ , mbCommentAuthorsRead(false)
+{
+ TextParagraphPropertiesArray& rParagraphDefaultsVector( mpTextListStyle->getListStyle() );
+ for (auto & elem : rParagraphDefaultsVector)
+ {
+ // ppt is having zero bottom margin per default, whereas OOo is 0,5cm,
+ // so this attribute needs to be set always
+ elem.getParaBottomMargin() = TextSpacing( 0 );
+ }
+}
+
+PresentationFragmentHandler::~PresentationFragmentHandler() noexcept
+{
+}
+
+static void lcl_setBookmark(uno::Reference<drawing::XShape>& rShape,
+ std::vector<SlidePersistPtr>& rSlidePersist)
+{
+ OUString aBookmark;
+ static const OUStringLiteral sSlideName = u"#page";
+ uno::Reference<beans::XPropertySet> xPropSet(rShape, uno::UNO_QUERY);
+ xPropSet->getPropertyValue("Bookmark") >>= aBookmark;
+ if (aBookmark.startsWith(sSlideName))
+ {
+ sal_Int32 nPageNumber = o3tl::toInt32(aBookmark.subView(sSlideName.getLength()));
+ Reference<XDrawPage> xDrawPage(rSlidePersist[nPageNumber - 1]->getPage());
+ Reference<container::XNamed> xNamed(xDrawPage, UNO_QUERY_THROW);
+ aBookmark = xNamed->getName();
+ xPropSet->setPropertyValue("Bookmark", Any(aBookmark));
+ }
+}
+
+static void ResolveShapeBookmark(std::vector<SlidePersistPtr>& rSlidePersist)
+{
+ sal_Int32 nPageCount = rSlidePersist.size();
+ for (sal_Int32 nPage = 0; nPage < nPageCount; ++nPage)
+ {
+ if (!rSlidePersist[nPage]->getURLShapeId().empty())
+ {
+ auto aShapeMap = rSlidePersist[nPage]->getShapeMap();
+ sal_Int32 nCount = rSlidePersist[nPage]->getURLShapeId().size();
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ OUString sId = rSlidePersist[nPage]->getURLShapeId()[i];
+ uno::Reference<drawing::XShape> xShape(aShapeMap[sId]->getXShape(), uno::UNO_QUERY);
+ Reference<XShapes> xShapes(xShape, UNO_QUERY);
+ if (xShapes.is()) // group shape
+ {
+ for (sal_Int32 j = 0; j < xShapes->getCount(); j++)
+ {
+ uno::Reference<drawing::XShape> xGroupedShape(xShapes->getByIndex(j),
+ uno::UNO_QUERY);
+ lcl_setBookmark(xGroupedShape, rSlidePersist);
+ }
+ }
+ else
+ lcl_setBookmark(xShape, rSlidePersist);
+ }
+ }
+ }
+}
+
+static void ResolveTextFields( XmlFilterBase const & rFilter )
+{
+ const oox::core::TextFieldStack& rTextFields = rFilter.getTextFieldStack();
+ if ( rTextFields.empty() )
+ return;
+
+ const Reference< frame::XModel >& xModel( rFilter.getModel() );
+ for (auto const& textField : rTextFields)
+ {
+ static const OUStringLiteral sURL = u"URL";
+ Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
+ Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
+
+ const oox::core::TextField& rTextField( textField );
+ Reference< XPropertySet > xPropSet( rTextField.xTextField, UNO_QUERY );
+ Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
+ if ( xPropSetInfo->hasPropertyByName( sURL ) )
+ {
+ OUString aURL;
+ if ( xPropSet->getPropertyValue( sURL ) >>= aURL )
+ {
+ static const OUStringLiteral sSlide = u"#Slide ";
+ static const OUStringLiteral sNotes = u"#Notes ";
+ bool bNotes = false;
+ sal_Int32 nPageNumber = 0;
+ if ( aURL.match( sSlide ) )
+ nPageNumber = o3tl::toInt32(aURL.subView( sSlide.getLength() ));
+ else if ( aURL.match( sNotes ) )
+ {
+ nPageNumber = o3tl::toInt32(aURL.subView( sNotes.getLength() ));
+ bNotes = true;
+ }
+ if ( nPageNumber )
+ {
+ try
+ {
+ Reference< XDrawPage > xDrawPage;
+ xDrawPages->getByIndex( nPageNumber - 1 ) >>= xDrawPage;
+ if ( bNotes )
+ {
+ Reference< css::presentation::XPresentationPage > xPresentationPage( xDrawPage, UNO_QUERY_THROW );
+ xDrawPage = xPresentationPage->getNotesPage();
+ }
+ Reference< container::XNamed > xNamed( xDrawPage, UNO_QUERY_THROW );
+ if (!xNamed->getName().startsWith("page"))
+ aURL = "#" + xNamed->getName();
+ else
+ aURL = "#" + URLResId(STR_SLIDE_NAME) + " " + OUString::number(nPageNumber);
+ xPropSet->setPropertyValue( sURL, Any( aURL ) );
+ Reference< text::XTextContent > xContent( rTextField.xTextField);
+ Reference< text::XTextRange > xTextRange = rTextField.xTextCursor;
+ rTextField.xText->insertTextContent( xTextRange, xContent, true );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ }
+ }
+ }
+}
+
+void PresentationFragmentHandler::importCustomSlideShow(std::vector<CustomShow>& rCustomShowList)
+{
+ PowerPointImport& rFilter = dynamic_cast<PowerPointImport&>(getFilter());
+ Reference<frame::XModel> xModel(rFilter.getModel());
+ Reference<XDrawPagesSupplier> xDrawPagesSupplier(xModel, UNO_QUERY_THROW);
+ Reference<XDrawPages> xDrawPages(xDrawPagesSupplier->getDrawPages(), UNO_SET_THROW);
+
+ Reference<css::lang::XSingleServiceFactory> mxShowFactory;
+ Reference<css::container::XNameContainer> mxShows;
+ Reference<XCustomPresentationSupplier> xShowsSupplier(xModel, UNO_QUERY);
+ if (xShowsSupplier.is())
+ {
+ mxShows = xShowsSupplier->getCustomPresentations();
+ mxShowFactory.set(mxShows, UNO_QUERY);
+ }
+
+ for (size_t i = 0; i < rCustomShowList.size(); ++i)
+ {
+ Reference<com::sun::star::container::XIndexContainer> xShow(mxShowFactory->createInstance(),
+ UNO_QUERY);
+ if (xShow.is())
+ {
+ static const OUStringLiteral sSlide = u"slides/slide";
+ for (size_t j = 0; j < rCustomShowList[i].maSldLst.size(); ++j)
+ {
+ OUString sCustomSlide = rCustomShowList[i].maSldLst[j];
+ sal_Int32 nPageNumber = 0;
+ if (sCustomSlide.match(sSlide))
+ nPageNumber = o3tl::toInt32(sCustomSlide.subView(sSlide.getLength()));
+
+ Reference<XDrawPage> xPage;
+ xDrawPages->getByIndex(nPageNumber - 1) >>= xPage;
+ if (xPage.is())
+ xShow->insertByIndex(xShow->getCount(), Any(xPage));
+ }
+
+ Any aAny;
+ aAny <<= xShow;
+ mxShows->insertByName(rCustomShowList[i].maCustomShowName, aAny);
+ }
+ }
+}
+
+void PresentationFragmentHandler::saveThemeToGrabBag(const oox::drawingml::ThemePtr& pThemePtr,
+ sal_Int32 nThemeIdx)
+{
+ if (!pThemePtr)
+ return;
+
+ try
+ {
+ uno::Reference<beans::XPropertySet> xDocProps(getFilter().getModel(), uno::UNO_QUERY);
+ if (xDocProps.is())
+ {
+ uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
+
+ static const OUStringLiteral aGrabBagPropName = u"InteropGrabBag";
+ if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
+ {
+ // get existing grab bag
+ comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
+
+ comphelper::SequenceAsHashMap aThemesHashMap;
+
+ // create current theme
+ uno::Sequence<beans::PropertyValue> aCurrentTheme(PredefinedClrSchemeId::Count);
+ auto pCurrentTheme = aCurrentTheme.getArray();
+
+ ClrScheme rClrScheme = pThemePtr->getClrScheme();
+ for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
+ {
+ sal_uInt32 nToken = PredefinedClrTokens[static_cast<PredefinedClrSchemeId>(nId)];
+ const OUString& sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
+ ::Color nColor;
+
+ rClrScheme.getColor(nToken, nColor);
+ const uno::Any& rColor = uno::Any(nColor);
+
+ pCurrentTheme[nId].Name = sName;
+ pCurrentTheme[nId].Value = rColor;
+ }
+
+
+ uno::Sequence<beans::PropertyValue> aTheme{
+ // add new theme to the sequence
+ // Export code uses the master slide's index to find the right theme
+ // so use the same index in the grabbag.
+ comphelper::makePropertyValue(
+ "ppt/theme/theme" + OUString::number(nThemeIdx) + ".xml", aCurrentTheme),
+ // store DOM fragment for SmartArt re-generation
+ comphelper::makePropertyValue("OOXTheme", pThemePtr->getFragment())
+ };
+
+ aThemesHashMap << aTheme;
+
+ // put the new items
+ aGrabBag.update(aThemesHashMap);
+
+ // put it back to the document
+ xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ SAL_WARN("oox", "oox::ppt::PresentationFragmentHandler::saveThemeToGrabBag, Failed to save grab bag");
+ }
+}
+
+void PresentationFragmentHandler::importSlide(sal_uInt32 nSlide, bool bFirstPage, bool bImportNotesPage)
+{
+ PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
+
+ Reference< frame::XModel > xModel( rFilter.getModel() );
+ Reference< drawing::XDrawPage > xSlide;
+
+ // importing slide pages and its corresponding notes page
+ Reference< drawing::XDrawPagesSupplier > xDPS( xModel, uno::UNO_QUERY_THROW );
+ Reference< drawing::XDrawPages > xDrawPages( xDPS->getDrawPages(), uno::UNO_SET_THROW );
+
+ try {
+
+ if( bFirstPage )
+ xDrawPages->getByIndex( 0 ) >>= xSlide;
+ else
+ xSlide = xDrawPages->insertNewByIndex( xDrawPages->getCount() );
+
+ OUString aSlideFragmentPath = getFragmentPathFromRelId( maSlidesVector[ nSlide ] );
+ if( !aSlideFragmentPath.isEmpty() )
+ {
+ SlidePersistPtr pMasterPersistPtr;
+ SlidePersistPtr pSlidePersistPtr = std::make_shared<SlidePersist>( rFilter, false, false, xSlide,
+ std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
+
+ FragmentHandlerRef xSlideFragmentHandler( new SlideFragmentHandler( rFilter, aSlideFragmentPath, pSlidePersistPtr, Slide ) );
+
+ // importing the corresponding masterpage/layout
+ OUString aLayoutFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideLayout" );
+ OUString aCommentFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"comments" );
+ if ( !aLayoutFragmentPath.isEmpty() )
+ {
+ // importing layout
+ RelationsRef xLayoutRelations = rFilter.importRelations( aLayoutFragmentPath );
+ OUString aMasterFragmentPath = xLayoutRelations->getFragmentPathFromFirstTypeFromOfficeDoc( u"slideMaster" );
+ if( !aMasterFragmentPath.isEmpty() )
+ {
+ // check if the corresponding masterpage+layout has already been imported
+ std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
+ for (auto const& masterPage : rMasterPages)
+ {
+ if ( ( masterPage->getPath() == aMasterFragmentPath ) && ( masterPage->getLayoutPath() == aLayoutFragmentPath ) )
+ {
+ pMasterPersistPtr = masterPage;
+ break;
+ }
+ }
+
+ if ( !pMasterPersistPtr )
+ { // masterpersist not found, we have to load it
+ Reference< drawing::XDrawPage > xMasterPage;
+ Reference< drawing::XMasterPagesSupplier > xMPS( xModel, uno::UNO_QUERY_THROW );
+ Reference< drawing::XDrawPages > xMasterPages( xMPS->getMasterPages(), uno::UNO_SET_THROW );
+
+ sal_Int32 nIndex;
+ if( rFilter.getMasterPages().empty() )
+ {
+ nIndex = 0;
+ xMasterPages->getByIndex( nIndex ) >>= xMasterPage;
+ }
+ else
+ {
+ nIndex = xMasterPages->getCount();
+ xMasterPage = xMasterPages->insertNewByIndex( nIndex );
+ }
+
+ pMasterPersistPtr = std::make_shared<SlidePersist>( rFilter, true, false, xMasterPage,
+ std::make_shared<PPTShape>( Master, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
+ pMasterPersistPtr->setLayoutPath( aLayoutFragmentPath );
+ rFilter.getMasterPages().push_back( pMasterPersistPtr );
+ rFilter.setActualSlidePersist( pMasterPersistPtr );
+ FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aMasterFragmentPath, pMasterPersistPtr, Master ) );
+
+ // set the correct theme
+ OUString aThemeFragmentPath = xMasterFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"theme" );
+ if( !aThemeFragmentPath.isEmpty() )
+ {
+ std::map< OUString, oox::drawingml::ThemePtr >& rThemes( rFilter.getThemes() );
+ std::map< OUString, oox::drawingml::ThemePtr >::iterator aIter2( rThemes.find( aThemeFragmentPath ) );
+ if( aIter2 == rThemes.end() )
+ {
+ oox::drawingml::ThemePtr pThemePtr = std::make_shared<oox::drawingml::Theme>();
+ pMasterPersistPtr->setTheme( pThemePtr );
+ Reference<xml::dom::XDocument> xDoc=
+ rFilter.importFragment(aThemeFragmentPath);
+
+ rFilter.importFragment(
+ new ThemeFragmentHandler(
+ rFilter, aThemeFragmentPath, *pThemePtr ),
+ Reference<xml::sax::XFastSAXSerializable>(
+ xDoc,
+ UNO_QUERY_THROW));
+ rThemes[ aThemeFragmentPath ] = pThemePtr;
+ pThemePtr->setFragment(xDoc);
+ saveThemeToGrabBag(pThemePtr, nIndex + 1);
+ }
+ else
+ {
+ pMasterPersistPtr->setTheme( (*aIter2).second );
+ }
+ }
+ importSlide( xMasterFragmentHandler, pMasterPersistPtr );
+ rFilter.importFragment( new LayoutFragmentHandler( rFilter, aLayoutFragmentPath, pMasterPersistPtr ) );
+ pMasterPersistPtr->createBackground( rFilter );
+ pMasterPersistPtr->createXShapes( rFilter );
+
+ oox::drawingml::ThemePtr pTheme = pMasterPersistPtr->getTheme();
+ if (pTheme)
+ {
+ pTheme->addTheme(pMasterPersistPtr->getPage());
+ }
+ }
+ }
+ }
+
+ // importing slide page
+ if (pMasterPersistPtr) {
+ pSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
+ pSlidePersistPtr->setTheme( pMasterPersistPtr->getTheme() );
+ Reference< drawing::XMasterPageTarget > xMasterPageTarget( pSlidePersistPtr->getPage(), UNO_QUERY );
+ if( xMasterPageTarget.is() )
+ xMasterPageTarget->setMasterPage( pMasterPersistPtr->getPage() );
+ }
+ rFilter.getDrawPages().push_back( pSlidePersistPtr );
+ rFilter.setActualSlidePersist( pSlidePersistPtr );
+ importSlide( xSlideFragmentHandler, pSlidePersistPtr );
+ pSlidePersistPtr->createBackground( rFilter );
+ pSlidePersistPtr->createXShapes( rFilter );
+
+ if(bImportNotesPage) {
+
+ // now importing the notes page
+ OUString aNotesFragmentPath = xSlideFragmentHandler->getFragmentPathFromFirstTypeFromOfficeDoc( u"notesSlide" );
+ if( !aNotesFragmentPath.isEmpty() )
+ {
+ Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
+ if ( xPresentationPage.is() )
+ {
+ Reference< XDrawPage > xNotesPage( xPresentationPage->getNotesPage() );
+ if ( xNotesPage.is() )
+ {
+ SlidePersistPtr pNotesPersistPtr = std::make_shared<SlidePersist>( rFilter, false, true, xNotesPage,
+ std::make_shared<PPTShape>( Slide, "com.sun.star.drawing.GroupShape" ), mpTextListStyle );
+ FragmentHandlerRef xNotesFragmentHandler( new SlideFragmentHandler( getFilter(), aNotesFragmentPath, pNotesPersistPtr, Slide ) );
+ rFilter.getNotesPages().push_back( pNotesPersistPtr );
+ rFilter.setActualSlidePersist( pNotesPersistPtr );
+ importSlide( xNotesFragmentHandler, pNotesPersistPtr );
+ pNotesPersistPtr->createBackground( rFilter );
+ pNotesPersistPtr->createXShapes( rFilter );
+ }
+ }
+ }
+ }
+
+ if( !mbCommentAuthorsRead && !aCommentFragmentPath.isEmpty() )
+ {
+ // Comments are present and commentAuthors.xml has still not been read
+ mbCommentAuthorsRead = true;
+ Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
+ Reference< XDrawPage > xCommentAuthorsPage( xPresentationPage->getNotesPage() );
+ SlidePersistPtr pCommentAuthorsPersistPtr =
+ std::make_shared<SlidePersist>( rFilter, false, true, xCommentAuthorsPage,
+ std::make_shared<PPTShape>(
+ Slide, "com.sun.star.drawing.GroupShape" ),
+ mpTextListStyle );
+ FragmentHandlerRef xCommentAuthorsFragmentHandler(
+ new SlideFragmentHandler( getFilter(),
+ "ppt/commentAuthors.xml",
+ pCommentAuthorsPersistPtr,
+ Slide ) );
+
+ getFilter().importFragment( xCommentAuthorsFragmentHandler );
+ maAuthorList.setValues( pCommentAuthorsPersistPtr->getCommentAuthors() );
+ }
+ if( !aCommentFragmentPath.isEmpty() )
+ {
+ Reference< XPresentationPage > xPresentationPage( xSlide, UNO_QUERY );
+ Reference< XDrawPage > xCommentsPage( xPresentationPage->getNotesPage() );
+ SlidePersistPtr pCommentsPersistPtr =
+ std::make_shared<SlidePersist>(
+ rFilter, false, true, xCommentsPage,
+ std::make_shared<PPTShape>(
+ Slide, "com.sun.star.drawing.GroupShape" ),
+ mpTextListStyle );
+
+ FragmentHandlerRef xCommentsFragmentHandler(
+ new SlideFragmentHandler(
+ getFilter(),
+ aCommentFragmentPath,
+ pCommentsPersistPtr,
+ Slide ) );
+ pCommentsPersistPtr->getCommentsList().cmLst.clear();
+ getFilter().importFragment( xCommentsFragmentHandler );
+
+ if (!pCommentsPersistPtr->getCommentsList().cmLst.empty())
+ {
+ //set comment chars for last comment on slide
+ SlideFragmentHandler* comment_handler =
+ dynamic_cast<SlideFragmentHandler*>(xCommentsFragmentHandler.get());
+ assert(comment_handler);
+ // some comments have no text -> set empty string as text to avoid
+ // crash (back() on empty vector is undefined) and losing other
+ // comment data that might be there (author, position, timestamp etc.)
+ pCommentsPersistPtr->getCommentsList().cmLst.back().setText(
+ comment_handler->getCharVector().empty() ? "" :
+ comment_handler->getCharVector().back() );
+ }
+ pCommentsPersistPtr->getCommentAuthors().setValues(maAuthorList);
+
+ //insert all comments from commentsList
+ for(int i=0; i<pCommentsPersistPtr->getCommentsList().getSize(); i++)
+ {
+ try {
+ Comment aComment = pCommentsPersistPtr->getCommentsList().getCommentAtIndex(i);
+ uno::Reference< office::XAnnotationAccess > xAnnotationAccess( xSlide, UNO_QUERY_THROW );
+ uno::Reference< office::XAnnotation > xAnnotation( xAnnotationAccess->createAndInsertAnnotation() );
+ int nPosX = aComment.getIntX();
+ int nPosY = aComment.getIntY();
+ xAnnotation->setPosition(
+ geometry::RealPoint2D(
+ ::oox::drawingml::convertEmuToHmm( nPosX ) * 15.87,
+ ::oox::drawingml::convertEmuToHmm( nPosY ) * 15.87 ) );
+ xAnnotation->setAuthor( aComment.getAuthor(maAuthorList) );
+ xAnnotation->setDateTime( aComment.getDateTime() );
+ uno::Reference< text::XText > xText( xAnnotation->getTextRange() );
+ xText->setString( aComment.get_text());
+ } catch( css::lang::IllegalArgumentException& ) {}
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::EndDocument()" );
+ }
+}
+
+void PresentationFragmentHandler::finalizeImport()
+{
+ PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
+
+ sal_Int32 nPageCount = maSlidesVector.size();
+
+ // we will take the FilterData property "PageRange" if available, otherwise full range is used
+ comphelper::SequenceAsHashMap& rFilterData = rFilter.getFilterData();
+
+ // writing back the original PageCount of this document, it can be accessed from the XModel
+ // via getArgs after the import.
+ rFilterData["OriginalPageCount"] <<= nPageCount;
+ bool bImportNotesPages = rFilterData.getUnpackedValueOrDefault("ImportNotesPages", true);
+ OUString aPageRange = rFilterData.getUnpackedValueOrDefault("PageRange", OUString());
+
+ if( !aPageRange.getLength() )
+ {
+ aPageRange = "1-" + OUString::number( nPageCount );
+ }
+
+ StringRangeEnumerator aRangeEnumerator( aPageRange, 0, nPageCount - 1 );
+ if (aRangeEnumerator.size())
+ {
+ // todo: localized progress bar text
+ const Reference< task::XStatusIndicator >& rxStatusIndicator( getFilter().getStatusIndicator() );
+ if ( rxStatusIndicator.is() )
+ rxStatusIndicator->start( OUString(), 10000 );
+
+ try
+ {
+ int nPagesImported = 0;
+ for (sal_Int32 elem : aRangeEnumerator)
+ {
+ if ( rxStatusIndicator.is() )
+ rxStatusIndicator->setValue((nPagesImported * 10000) / aRangeEnumerator.size());
+
+ importSlide(elem, !nPagesImported, bImportNotesPages);
+ nPagesImported++;
+ }
+ ResolveTextFields( rFilter );
+ ResolveShapeBookmark(rFilter.getDrawPages());
+ if (!maCustomShowList.empty())
+ importCustomSlideShow(maCustomShowList);
+ }
+ catch( uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::PresentationFragmentHandler::finalizeImport()" );
+ }
+ // todo error handling;
+ if ( rxStatusIndicator.is() )
+ rxStatusIndicator->end();
+ }
+
+ // open the VBA project storage
+ OUString aVbaFragmentPath = getFragmentPathFromFirstType(CREATE_MSOFFICE_RELATION_TYPE("vbaProject"));
+ if (!aVbaFragmentPath.isEmpty())
+ {
+ uno::Reference<io::XInputStream> xInStrm = getFilter().openInputStream(aVbaFragmentPath);
+ if (xInStrm.is())
+ {
+ StorageRef xPrjStrg = std::make_shared<oox::ole::OleStorage>(getFilter().getComponentContext(), xInStrm, false);
+ getFilter().getVbaProject().importVbaProject(*xPrjStrg);
+ }
+ }
+}
+
+// CT_Presentation
+::oox::core::ContextHandlerRef PresentationFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( presentation ):
+ case PPT_TOKEN( sldMasterIdLst ):
+ case PPT_TOKEN( notesMasterIdLst ):
+ case PPT_TOKEN( sldIdLst ):
+ return this;
+ case PPT_TOKEN( sldMasterId ):
+ maSlideMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ return this;
+ case PPT_TOKEN( sldId ):
+ maSlidesVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ return this;
+ case PPT_TOKEN( notesMasterId ):
+ maNotesMasterVector.push_back( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ return this;
+ case PPT_TOKEN( sldSz ):
+ maSlideSize = GetSize2D( rAttribs.getFastAttributeList() );
+ return this;
+ case PPT_TOKEN( notesSz ):
+ maNotesSize = GetSize2D( rAttribs.getFastAttributeList() );
+ return this;
+ case PPT_TOKEN( custShowLst ):
+ return new CustomShowListContext( *this, maCustomShowList );
+ case PPT_TOKEN( defaultTextStyle ):
+ return new TextListStyleContext( *this, *mpTextListStyle );
+ case PPT_TOKEN( modifyVerifier ):
+ OUString sAlgorithmClass = rAttribs.getString(XML_cryptAlgorithmClass, OUString());
+ OUString sAlgorithmType = rAttribs.getString(XML_cryptAlgorithmType, OUString());
+ sal_Int32 nAlgorithmSid = rAttribs.getInteger(XML_cryptAlgorithmSid, 0);
+ sal_Int32 nSpinCount = rAttribs.getInteger(XML_spinCount, 0);
+ OUString sSalt = rAttribs.getString(XML_saltData, OUString());
+ OUString sHash = rAttribs.getString(XML_hashData, OUString());
+ if (sAlgorithmClass == "hash" && sAlgorithmType == "typeAny" && nAlgorithmSid != 0
+ && !sSalt.isEmpty() && !sHash.isEmpty())
+ {
+ OUString sAlgorithmName;
+ switch (nAlgorithmSid)
+ {
+ case 1:
+ sAlgorithmName = "MD2";
+ break;
+ case 2:
+ sAlgorithmName = "MD4";
+ break;
+ case 3:
+ sAlgorithmName = "MD5";
+ break;
+ case 4:
+ sAlgorithmName = "SHA-1";
+ break;
+ case 5:
+ sAlgorithmName = "MAC";
+ break;
+ case 6:
+ sAlgorithmName = "RIPEMD";
+ break;
+ case 7:
+ sAlgorithmName = "RIPEMD-160";
+ break;
+ case 9:
+ sAlgorithmName = "HMAC";
+ break;
+ case 12:
+ sAlgorithmName = "SHA-256";
+ break;
+ case 13:
+ sAlgorithmName = "SHA-384";
+ break;
+ case 14:
+ sAlgorithmName = "SHA-512";
+ break;
+ default:; // 8, 10, 11, any other value: Undefined.
+ }
+
+ if (!sAlgorithmName.isEmpty())
+ {
+ uno::Sequence<beans::PropertyValue> aResult{
+ comphelper::makePropertyValue("algorithm-name", sAlgorithmName),
+ comphelper::makePropertyValue("salt", sSalt),
+ comphelper::makePropertyValue("iteration-count", nSpinCount),
+ comphelper::makePropertyValue("hash", sHash)
+ };
+ try
+ {
+ uno::Reference<beans::XPropertySet> xDocSettings(
+ getFilter().getModelFactory()->createInstance(
+ "com.sun.star.document.Settings"),
+ uno::UNO_QUERY);
+ xDocSettings->setPropertyValue("ModifyPasswordInfo", uno::Any(aResult));
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+ }
+ return this;
+ }
+ return this;
+}
+
+void PresentationFragmentHandler::importSlide( const FragmentHandlerRef& rxSlideFragmentHandler,
+ const SlidePersistPtr& rSlidePersistPtr )
+{
+ Reference< drawing::XDrawPage > xSlide( rSlidePersistPtr->getPage() );
+ SlidePersistPtr pMasterPersistPtr( rSlidePersistPtr->getMasterPersist() );
+ if ( pMasterPersistPtr )
+ {
+ // Setting "Layout" property adds extra title and outliner preset shapes to the master slide
+ Reference< drawing::XDrawPage > xMasterSlide(pMasterPersistPtr->getPage());
+ const int nCount = xMasterSlide->getCount();
+
+ uno::Reference< beans::XPropertySet > xSet( xSlide, uno::UNO_QUERY_THROW );
+ xSet->setPropertyValue( "Layout", Any( pMasterPersistPtr->getLayoutFromValueToken() ) );
+
+ while( nCount < xMasterSlide->getCount())
+ {
+ Reference< drawing::XShape > xShape;
+ xMasterSlide->getByIndex(xMasterSlide->getCount()-1) >>= xShape;
+ xMasterSlide->remove(xShape);
+ }
+ }
+ while( xSlide->getCount() )
+ {
+ Reference< drawing::XShape > xShape;
+ xSlide->getByIndex(0) >>= xShape;
+ xSlide->remove( xShape );
+ }
+
+ Reference< XPropertySet > xPropertySet( xSlide, UNO_QUERY );
+ if ( xPropertySet.is() )
+ {
+ awt::Size& rPageSize( rSlidePersistPtr->isNotesPage() ? maNotesSize : maSlideSize );
+ xPropertySet->setPropertyValue( "Width", Any( rPageSize.Width ) );
+ xPropertySet->setPropertyValue( "Height", Any( rPageSize.Height ) );
+
+ oox::ppt::HeaderFooter aHeaderFooter( rSlidePersistPtr->getHeaderFooter() );
+ if ( !rSlidePersistPtr->isMasterPage() )
+ aHeaderFooter.mbSlideNumber = aHeaderFooter.mbHeader = aHeaderFooter.mbFooter = aHeaderFooter.mbDateTime = false;
+ try
+ {
+ if ( rSlidePersistPtr->isNotesPage() )
+ xPropertySet->setPropertyValue( "IsHeaderVisible", Any( aHeaderFooter.mbHeader ) );
+ xPropertySet->setPropertyValue( "IsFooterVisible", Any( aHeaderFooter.mbFooter ) );
+ xPropertySet->setPropertyValue( "IsDateTimeVisible", Any( aHeaderFooter.mbDateTime ) );
+ xPropertySet->setPropertyValue( "IsPageNumberVisible", Any( aHeaderFooter.mbSlideNumber ) );
+ }
+ catch( uno::Exception& )
+ {
+ }
+ }
+ rSlidePersistPtr->setPath( rxSlideFragmentHandler->getFragmentPath() );
+ getFilter().importFragment( rxSlideFragmentHandler );
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/slidefragmenthandler.cxx b/oox/source/ppt/slidefragmenthandler.cxx
new file mode 100644
index 000000000..79ea427b5
--- /dev/null
+++ b/oox/source/ppt/slidefragmenthandler.cxx
@@ -0,0 +1,265 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <tools/diagnose_ex.h>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/helper/propertyset.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include "headerfootercontext.hxx"
+#include <oox/ppt/backgroundproperties.hxx>
+#include <oox/ppt/slidefragmenthandler.hxx>
+#include <oox/ppt/slidetimingcontext.hxx>
+#include <oox/ppt/slidetransitioncontext.hxx>
+#include <oox/ppt/slidemastertextstylescontext.hxx>
+#include <oox/ppt/pptshapegroupcontext.hxx>
+#include <oox/ppt/pptshape.hxx>
+#include <oox/vml/vmldrawing.hxx>
+#include <oox/vml/vmldrawingfragment.hxx>
+#include <drawingml/clrschemecontext.hxx>
+#include <drawingml/fillproperties.hxx>
+#include <oox/ppt/pptimport.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/properties.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::container;
+
+namespace oox::ppt {
+
+SlideFragmentHandler::SlideFragmentHandler( XmlFilterBase& rFilter, const OUString& rFragmentPath, const SlidePersistPtr& pPersistPtr, const ShapeLocation eShapeLocation )
+: FragmentHandler2( rFilter, rFragmentPath )
+, mpSlidePersistPtr( pPersistPtr )
+, meShapeLocation( eShapeLocation )
+{
+ OUString aVMLDrawingFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( u"vmlDrawing" );
+ if( !aVMLDrawingFragmentPath.isEmpty() )
+ getFilter().importFragment( new oox::vml::DrawingFragment(
+ getFilter(), aVMLDrawingFragmentPath, *pPersistPtr->getDrawing() ) );
+}
+
+SlideFragmentHandler::~SlideFragmentHandler()
+{
+ // convert and insert all VML shapes (mostly form controls)
+ mpSlidePersistPtr->getDrawing()->convertAndInsert();
+}
+
+::oox::core::ContextHandlerRef SlideFragmentHandler::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( sldMaster ): // CT_SlideMaster
+ case PPT_TOKEN( handoutMaster ): // CT_HandoutMaster
+ case PPT_TOKEN( sld ): // CT_CommonSlideData
+ {
+ Reference< XDrawPage > xSlide( mpSlidePersistPtr->getPage() );
+ Reference< css::beans::XPropertySet > xSet(xSlide, UNO_QUERY);
+ PropertyMap aPropMap;
+ PropertySet aSlideProp( xSlide );
+
+ OptValue<bool> aShowMasterShapes = rAttribs.getBool(XML_showMasterSp);
+ if (aShowMasterShapes.has() && !aShowMasterShapes.get())
+ xSet->setPropertyValue("IsBackgroundObjectsVisible", Any(false));
+
+ aPropMap.setProperty( PROP_Visible, rAttribs.getBool( XML_show, true ));
+ aSlideProp.setProperties( aPropMap );
+
+ return this;
+ }
+ case PPT_TOKEN( notes ): // CT_NotesSlide
+ {
+ // Import notesMaster
+ PowerPointImport& rFilter = dynamic_cast< PowerPointImport& >( getFilter() );
+ OUString aNotesFragmentPath = getFragmentPathFromFirstTypeFromOfficeDoc( u"notesMaster" );
+
+ std::vector< SlidePersistPtr >& rMasterPages( rFilter.getMasterPages() );
+ bool bNotesFragmentPathFound = false;
+ for (auto const& masterPage : rMasterPages)
+ {
+ if( masterPage->getPath() == aNotesFragmentPath )
+ {
+ if( !mpSlidePersistPtr->getMasterPersist() )
+ mpSlidePersistPtr->setMasterPersist(masterPage);
+ bNotesFragmentPathFound=true;
+ break;
+ }
+ }
+ if( !bNotesFragmentPathFound && !mpSlidePersistPtr->getMasterPersist() )
+ {
+ SlidePersistPtr pMasterPersistPtr = std::make_shared<SlidePersist>( rFilter, true, true, mpSlidePersistPtr->getPage(),
+ std::make_shared<PPTShape>( Master, "com.sun.star.drawing.GroupShape" ), mpSlidePersistPtr->getNotesTextStyle() );
+ pMasterPersistPtr->setPath( aNotesFragmentPath );
+ rFilter.getMasterPages().push_back( pMasterPersistPtr );
+ FragmentHandlerRef xMasterFragmentHandler( new SlideFragmentHandler( rFilter, aNotesFragmentPath, pMasterPersistPtr, Master ) );
+ rFilter.importFragment( xMasterFragmentHandler );
+ mpSlidePersistPtr->setMasterPersist( pMasterPersistPtr );
+ }
+ return this;
+ }
+ case PPT_TOKEN( notesMaster ): // CT_NotesMaster
+ return this;
+ case PPT_TOKEN( cSld ): // CT_CommonSlideData
+ maSlideName = rAttribs.getString(XML_name, OUString());
+ return this;
+
+ case PPT_TOKEN( spTree ): // CT_GroupShape
+ {
+ return new PPTShapeGroupContext(
+ *this, mpSlidePersistPtr, meShapeLocation, mpSlidePersistPtr->getShapes(),
+ std::make_shared<PPTShape>( meShapeLocation, "com.sun.star.drawing.GroupShape" ) );
+ }
+ break;
+
+ case PPT_TOKEN( controls ):
+ return this;
+ case PPT_TOKEN( control ):
+ {
+ ::oox::vml::ControlInfo aInfo;
+ aInfo.setShapeId( rAttribs.getInteger( XML_spid, 0 ) );
+ aInfo.maFragmentPath = getFragmentPathFromRelId( rAttribs.getString( R_TOKEN( id ), OUString() ) );
+ aInfo.maName = rAttribs.getXString( XML_name, OUString() );
+ mpSlidePersistPtr->getDrawing()->registerControl( aInfo );
+ }
+ return this;
+
+ case PPT_TOKEN( timing ): // CT_SlideTiming
+ return new SlideTimingContext( *this, mpSlidePersistPtr->getTimeNodeList() );
+ case PPT_TOKEN( transition ): // CT_SlideTransition
+ return new SlideTransitionContext( *this, rAttribs, maSlideProperties );
+ case PPT_TOKEN( hf ):
+ return new HeaderFooterContext( *this, rAttribs, mpSlidePersistPtr->getHeaderFooter() );
+
+ // BackgroundGroup
+ case PPT_TOKEN( bg ):
+ return this;
+ case PPT_TOKEN( bgPr ): // CT_BackgroundProperties
+ {
+ FillPropertiesPtr pFillPropertiesPtr =std::make_shared<FillProperties>();
+ mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr );
+ return new BackgroundPropertiesContext( *this, *pFillPropertiesPtr );
+ }
+ break;
+
+ case PPT_TOKEN( bgRef ): // a:CT_StyleMatrixReference
+ {
+ const FillProperties *pFillProperties = nullptr;
+ if( mpSlidePersistPtr->getTheme() )
+ pFillProperties = mpSlidePersistPtr->getTheme()->getFillStyle( rAttribs.getInteger( XML_idx, -1 ) );
+ FillPropertiesPtr pFillPropertiesPtr =
+ pFillProperties
+ ? std::make_shared<FillProperties>( *pFillProperties )
+ : std::make_shared<FillProperties>();
+ mpSlidePersistPtr->setBackgroundProperties( pFillPropertiesPtr );
+ ContextHandlerRef ret = new ColorContext( *this, mpSlidePersistPtr->getBackgroundColor() );
+ return ret;
+ }
+ break;
+
+ case A_TOKEN( overrideClrMapping ):
+ case PPT_TOKEN( clrMap ): // CT_ColorMapping
+ {
+ oox::drawingml::ClrMapPtr pClrMapPtr =
+ ( aElementToken == PPT_TOKEN( clrMap ) || !mpSlidePersistPtr || !mpSlidePersistPtr->getClrMap() )
+ ? std::make_shared<oox::drawingml::ClrMap>()
+ : std::make_shared<oox::drawingml::ClrMap>( *mpSlidePersistPtr->getClrMap() );
+ ContextHandlerRef ret = new oox::drawingml::clrMapContext( *this, rAttribs, *pClrMapPtr );
+ mpSlidePersistPtr->setClrMap( pClrMapPtr );
+ return ret;
+ }
+ break;
+ case PPT_TOKEN( clrMapOvr ): // CT_ColorMappingOverride
+ case PPT_TOKEN( sldLayoutIdLst ): // CT_SlideLayoutIdList
+ return this;
+ case PPT_TOKEN( txStyles ): // CT_SlideMasterTextStyles
+ return new SlideMasterTextStylesContext( *this, mpSlidePersistPtr );
+ case PPT_TOKEN( custDataLst ): // CT_CustomerDataList
+ case PPT_TOKEN( tagLst ): // CT_TagList
+ return this;
+
+ //for Comments
+ case PPT_TOKEN( cmLst ):
+ break;
+ case PPT_TOKEN( cm ):
+ if (!mpSlidePersistPtr->getCommentsList().cmLst.empty() && !getCharVector().empty())
+ {
+ // set comment text for earlier comment
+ mpSlidePersistPtr->getCommentsList().cmLst.back().setText( getCharVector().back() );
+ }
+ // insert a new comment in vector commentsList
+ mpSlidePersistPtr->getCommentsList().cmLst.emplace_back();
+ mpSlidePersistPtr->getCommentsList().cmLst.back().setAuthorId(rAttribs.getString(XML_authorId, OUString()));
+ mpSlidePersistPtr->getCommentsList().cmLst.back().setdt(rAttribs.getString(XML_dt, OUString()));
+ mpSlidePersistPtr->getCommentsList().cmLst.back().setidx(rAttribs.getString(XML_idx, OUString()));
+ break;
+
+ case PPT_TOKEN( pos ):
+ mpSlidePersistPtr->getCommentsList().cmLst.back().setPoint(
+ rAttribs.getString(XML_x, OUString()),
+ rAttribs.getString(XML_y, OUString()));
+ break;
+
+ case PPT_TOKEN( cmAuthor ):
+ CommentAuthor _author;
+ _author.clrIdx = rAttribs.getString(XML_clrIdx, OUString());
+ _author.id = rAttribs.getString(XML_id, OUString());
+ _author.initials = rAttribs.getString(XML_initials, OUString());
+ _author.lastIdx = rAttribs.getString(XML_lastIdx, OUString());
+ _author.name = rAttribs.getString(XML_name, OUString());
+ mpSlidePersistPtr->getCommentAuthors().addAuthor(_author);
+ break;
+ }
+
+ return this;
+}
+void SlideFragmentHandler::onCharacters( const OUString& rChars)
+{
+ maCharVector.push_back(rChars);
+}
+void SlideFragmentHandler::finalizeImport()
+{
+ try
+ {
+ Reference< XDrawPage > xSlide( mpSlidePersistPtr->getPage() );
+ PropertySet aSlideProp( xSlide );
+ aSlideProp.setProperties( maSlideProperties );
+ if ( !maSlideName.isEmpty() )
+ {
+ Reference< XNamed > xNamed( xSlide, UNO_QUERY );
+ if( xNamed.is() )
+ xNamed->setName( maSlideName );
+ }
+ }
+ catch( uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "oox", "oox::ppt::SlideFragmentHandler::EndElement()" );
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/slidemastertextstylescontext.cxx b/oox/source/ppt/slidemastertextstylescontext.cxx
new file mode 100644
index 000000000..de326c9bb
--- /dev/null
+++ b/oox/source/ppt/slidemastertextstylescontext.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <drawingml/textliststyle.hxx>
+#include <drawingml/textliststylecontext.hxx>
+#include <oox/ppt/slidemastertextstylescontext.hxx>
+#include <oox/token/namespaces.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+SlideMasterTextStylesContext::SlideMasterTextStylesContext( FragmentHandler2 const & rParent, SlidePersistPtr const & pSlidePersistPtr )
+: FragmentHandler2( rParent )
+, mpSlidePersistPtr( pSlidePersistPtr )
+{
+}
+
+SlideMasterTextStylesContext::~SlideMasterTextStylesContext()
+{
+}
+
+::oox::core::ContextHandlerRef SlideMasterTextStylesContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ )
+{
+ oox::drawingml::TextListStylePtr aTextListStylePtr;
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( titleStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getTitleTextStyle();
+ break;
+ }
+ case PPT_TOKEN( bodyStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getBodyTextStyle();
+ break;
+ }
+ case PPT_TOKEN( notesStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getNotesTextStyle();
+ break;
+ }
+ case PPT_TOKEN( otherStyle ):
+ {
+ aTextListStylePtr = mpSlidePersistPtr->getOtherTextStyle();
+ break;
+ }
+ }
+ if ( aTextListStylePtr ) // sj: the master list style is the last instance of from where properties
+ { // are obtained. i got some documents without having the textsize set at
+ for ( int i = 0; i < 9; i++ ) // any point, the master reference application is using 18pt then
+ aTextListStylePtr->getListStyle()[ i ].getTextCharacterProperties().moHeight = 1800;
+ return new oox::drawingml::TextListStyleContext( *this, *aTextListStylePtr );
+ }
+
+ return this;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx
new file mode 100644
index 000000000..dc068b0b6
--- /dev/null
+++ b/oox/source/ppt/slidepersist.cxx
@@ -0,0 +1,555 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <oox/ppt/timenode.hxx>
+#include <oox/ppt/pptshape.hxx>
+#include <oox/ppt/slidepersist.hxx>
+#include <drawingml/fillproperties.hxx>
+#include <oox/drawingml/shapepropertymap.hxx>
+#include <oox/helper/propertymap.hxx>
+#include <oox/helper/propertyset.hxx>
+#include <oox/vml/vmldrawing.hxx>
+#include <oox/token/properties.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <drawingml/textliststyle.hxx>
+#include <drawingml/textparagraphproperties.hxx>
+
+#include <osl/diagnose.h>
+
+#include <com/sun/star/style/XStyle.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/container/XNamed.hpp>
+#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/container/XIdentifierContainer.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/ConnectorType.hpp>
+#include <svx/svdobj.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::animations;
+
+
+namespace oox::ppt {
+
+SlidePersist::SlidePersist( XmlFilterBase& rFilter, bool bMaster, bool bNotes,
+ const css::uno::Reference< css::drawing::XDrawPage >& rxPage,
+ oox::drawingml::ShapePtr const & pShapesPtr, const drawingml::TextListStylePtr & pDefaultTextStyle )
+: mpDrawingPtr( std::make_shared<oox::vml::Drawing>( rFilter, rxPage, oox::vml::VMLDRAWING_POWERPOINT ) )
+, mxPage( rxPage )
+, maShapesPtr( pShapesPtr )
+, mnLayoutValueToken( 0 )
+, mbMaster( bMaster )
+, mbNotes ( bNotes )
+, maDefaultTextStylePtr( pDefaultTextStyle )
+, maTitleTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
+, maBodyTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
+, maNotesTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
+, maOtherTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
+{
+#if OSL_DEBUG_LEVEL > 0
+ mxDebugPage = mxPage;
+#endif
+}
+
+#if OSL_DEBUG_LEVEL > 0
+css::uno::WeakReference< css::drawing::XDrawPage > SlidePersist::mxDebugPage;
+#endif
+
+SlidePersist::~SlidePersist()
+{
+}
+
+sal_Int16 SlidePersist::getLayoutFromValueToken() const
+{
+ sal_Int16 nLayout = 20; // 20 == blank (so many magic numbers :-( the description at com.sun.star.presentation.DrawPage.Layout does not help)
+ switch( mnLayoutValueToken )
+ {
+ case XML_blank: nLayout = 20; break;
+ case XML_chart: nLayout = 2; break;
+ case XML_chartAndTx: nLayout = 7; break;
+ case XML_clipArtAndTx: nLayout = 9; break;
+ case XML_clipArtAndVertTx: nLayout = 24; break;
+ case XML_fourObj: nLayout = 18; break;
+ case XML_obj: nLayout = 11; break;
+ case XML_objAndTx: nLayout = 13; break;
+ case XML_objOverTx: nLayout = 14; break;
+ case XML_tbl: nLayout = 8; break;
+ case XML_title: nLayout = 0; break;
+ case XML_titleOnly: nLayout = 19; break;
+ case XML_twoObj:
+ case XML_twoColTx: nLayout = 3; break;
+ case XML_twoObjAndTx: nLayout = 15; break;
+ case XML_twoObjOverTx: nLayout = 16; break;
+ case XML_tx: nLayout = 1; break;
+ case XML_txAndChart: nLayout = 4; break;
+ case XML_txAndClipArt: nLayout = 6; break;
+ case XML_txAndMedia: nLayout = 6; break;
+ case XML_txAndObj: nLayout = 10; break;
+ case XML_txAndTwoObj: nLayout = 12; break;
+ case XML_txOverObj: nLayout = 17; break;
+ case XML_vertTitleAndTx: nLayout = 22; break;
+ case XML_vertTitleAndTxOverChart: nLayout = 21; break;
+ case XML_vertTx: nLayout = 23; break;
+
+ case XML_twoTxTwoObj:
+ case XML_twoObjAndObj:
+ case XML_objTx:
+ case XML_picTx:
+ case XML_secHead:
+ case XML_objOnly:
+ case XML_objAndTwoObj:
+ case XML_mediaAndTx:
+ case XML_dgm:
+ case XML_cust:
+ default:
+ nLayout = 20;
+ }
+ return nLayout;
+}
+
+void SlidePersist::createXShapes( XmlFilterBase& rFilterBase )
+{
+ applyTextStyles( rFilterBase );
+
+ Reference< XShapes > xShapes( getPage() );
+ std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
+
+ for (auto const& shape : rShapes)
+ {
+ std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() );
+ for (auto const& child : rChildren)
+ {
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
+ basegfx::B2DHomMatrix aTransformation;
+ if ( pPPTShape )
+ {
+ pPPTShape->addShape( rFilterBase, *this, getTheme().get(), xShapes, aTransformation, &getShapeMap() );
+ if (pPPTShape->isConnectorShape())
+ maConnectorShapeId.push_back(pPPTShape->getId());
+ if (!pPPTShape->getChildren().empty())
+ {
+ for (size_t i = 0; i < pPPTShape->getChildren().size(); i++)
+ {
+ if (pPPTShape->getChildren()[i]->isConnectorShape())
+ maConnectorShapeId.push_back(pPPTShape->getChildren()[i]->getId());
+ }
+ }
+ if (pPPTShape->hasBookmark())
+ addURLShapeId(pPPTShape->getId());
+ }
+ else
+ child->addShape( rFilterBase, getTheme().get(), xShapes, aTransformation, maShapesPtr->getFillProperties(), &getShapeMap() );
+ }
+ }
+
+ if (!maConnectorShapeId.empty())
+ createConnectorShapeConnection();
+
+ Reference< XAnimationNodeSupplier > xNodeSupplier( getPage(), UNO_QUERY);
+ if( !xNodeSupplier.is() )
+ return;
+
+ Reference< XAnimationNode > xNode( xNodeSupplier->getAnimationNode() );
+ if( xNode.is() && !maTimeNodeList.empty() )
+ {
+ SlidePersistPtr pSlidePtr( shared_from_this() );
+ TimeNodePtr pNode(maTimeNodeList.front());
+ OSL_ENSURE( pNode, "pNode" );
+
+ Reference<XAnimationNode> xDummy;
+ pNode->setNode(rFilterBase, xNode, pSlidePtr, xDummy);
+ }
+}
+
+void SlidePersist::createBackground( const XmlFilterBase& rFilterBase )
+{
+ if ( mpBackgroundPropertiesPtr )
+ {
+ ::Color nPhClr = maBackgroundColor.isUsed() ?
+ maBackgroundColor.getColor( rFilterBase.getGraphicHelper() ) : API_RGB_TRANSPARENT;
+
+ oox::drawingml::ShapePropertyIds aPropertyIds = oox::drawingml::ShapePropertyInfo::DEFAULT.mrPropertyIds;
+ aPropertyIds[oox::drawingml::ShapeProperty::FillGradient] = PROP_FillGradientName;
+ oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false, false );
+ oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper(), aPropInfo );
+ mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr );
+ PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() );
+ }
+}
+
+static void setTextStyle( Reference< beans::XPropertySet > const & rxPropSet, const XmlFilterBase& rFilter,
+ oox::drawingml::TextListStylePtr const & pTextListStylePtr, int nLevel )
+{
+ ::oox::drawingml::TextParagraphProperties* pTextParagraphPropertiesPtr( &pTextListStylePtr->getListStyle()[ nLevel ] );
+ if( pTextParagraphPropertiesPtr == nullptr )
+ {
+ // no properties. return
+ return;
+ }
+
+ PropertyMap& rTextParagraphPropertyMap( pTextParagraphPropertiesPtr->getTextParagraphPropertyMap() );
+
+ PropertySet aPropSet( rxPropSet );
+ aPropSet.setProperties( rTextParagraphPropertyMap );
+ pTextParagraphPropertiesPtr->getTextCharacterProperties().pushToPropSet( aPropSet, rFilter );
+}
+
+void SlidePersist::applyTextStyles( const XmlFilterBase& rFilterBase )
+{
+ if ( !mbMaster )
+ return;
+
+ try
+ {
+ Reference< style::XStyleFamiliesSupplier > aXStyleFamiliesSupplier( rFilterBase.getModel(), UNO_QUERY_THROW );
+ Reference< container::XNameAccess > aXNameAccess( aXStyleFamiliesSupplier->getStyleFamilies() );
+ Reference< container::XNamed > aXNamed( mxPage, UNO_QUERY_THROW );
+
+ if ( aXNameAccess.is() )
+ {
+ oox::drawingml::TextListStylePtr pTextListStylePtr;
+ OUString aStyle;
+ OUString aFamily;
+
+ static const OUStringLiteral sOutline( u"outline1" );
+ static const OUStringLiteral sTitle( u"title" );
+ static const OUStringLiteral sStandard( u"standard" );
+ static const OUStringLiteral sSubtitle( u"subtitle" );
+
+ for( int i = 0; i < 4; i++ ) // todo: aggregation of bodystyle (subtitle)
+ {
+ switch( i )
+ {
+ case 0 : // title style
+ {
+ pTextListStylePtr = maTitleTextStylePtr;
+ aStyle = sTitle;
+ aFamily= aXNamed->getName();
+ break;
+ }
+ case 1 : // body style
+ {
+ pTextListStylePtr = maBodyTextStylePtr;
+ aStyle = sOutline;
+ aFamily= aXNamed->getName();
+ break;
+ }
+ case 3 : // notes style
+ {
+ pTextListStylePtr = maNotesTextStylePtr;
+ aStyle = sTitle;
+ aFamily= aXNamed->getName();
+ break;
+ }
+ case 4 : // standard style
+ {
+ pTextListStylePtr = maOtherTextStylePtr;
+ aStyle = sStandard;
+ aFamily = "graphics";
+ break;
+ }
+ case 5 : // subtitle
+ {
+ pTextListStylePtr = maBodyTextStylePtr;
+ aStyle = sSubtitle;
+ aFamily = aXNamed->getName();
+ break;
+ }
+ }
+ Reference< container::XNameAccess > xFamilies;
+ if ( aXNameAccess->hasByName( aFamily ) )
+ {
+ if( aXNameAccess->getByName( aFamily ) >>= xFamilies )
+ {
+ if ( xFamilies->hasByName( aStyle ) )
+ {
+ Reference< style::XStyle > aXStyle;
+ if ( xFamilies->getByName( aStyle ) >>= aXStyle )
+ {
+ Reference< beans::XPropertySet > xPropSet( aXStyle, UNO_QUERY_THROW );
+ setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, 0 );
+ setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, 0 );
+ if ( i == 1 /* BodyStyle */ )
+ {
+ for ( int nLevel = 1; nLevel < 5; nLevel++ )
+ {
+ {
+ char pOutline[ 9 ] = "outline1";
+ pOutline[ 7 ] = static_cast< char >( '0' + nLevel );
+ OUString sOutlineStyle( OUString::createFromAscii( pOutline ) );
+ if ( xFamilies->hasByName( sOutlineStyle ) )
+ {
+ xFamilies->getByName( sOutlineStyle ) >>= aXStyle;
+ if( aXStyle.is() )
+ xPropSet.set( aXStyle, UNO_QUERY_THROW );
+ }
+ }
+ setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, nLevel );
+ setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, nLevel );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+}
+
+void SlidePersist::hideShapesAsMasterShapes()
+{
+ std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
+ for (auto const& shape : rShapes)
+ {
+ std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() );
+ for (auto const& child : rChildren)
+ {
+ PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
+ if (!pPPTShape)
+ continue;
+ pPPTShape->setHiddenMasterShape( true );
+ }
+ }
+}
+
+// This angle determines in the direction of the line
+static sal_Int32 lcl_GetAngle(uno::Reference<drawing::XShape>& rXShape, awt::Point& rPt)
+{
+ SdrObject* pObj = SdrObject::getSdrObjectFromXShape(rXShape);
+ tools::Rectangle aR(pObj->GetSnapRect());
+ sal_Int32 nLeftX = rPt.X - aR.Left();
+ sal_Int32 nTopY = rPt.Y - aR.Top();
+ sal_Int32 nRightX = aR.Right() - rPt.X;
+ sal_Int32 nBottomY = aR.Bottom() - rPt.Y;
+ sal_Int32 nX = std::min(nLeftX, nRightX);
+ sal_Int32 nY = std::min(nTopY, nBottomY);
+
+ sal_Int32 nAngle;
+ if (nX < nY)
+ {
+ if (nLeftX < nRightX)
+ nAngle = 180; // Left
+ else
+ nAngle = 0; // Right
+ }
+ else
+ {
+ if (nTopY < nBottomY)
+ nAngle = 270; // Top
+ else
+ nAngle = 90; // Bottom
+ }
+ return nAngle;
+}
+
+Reference<XAnimationNode> SlidePersist::getAnimationNode(const OUString& sId) const
+{
+ const auto& pIter = maAnimNodesMap.find(sId);
+ if (pIter != maAnimNodesMap.end())
+ return pIter->second;
+
+ Reference<XAnimationNode> aResult;
+ return aResult;
+}
+
+static void lcl_SetEdgeLineValue(uno::Reference<drawing::XShape>& rXConnector,
+ oox::drawingml::ShapePtr& rShapePtr)
+{
+ sal_Int32 nEdge = 0;
+ awt::Point aStartPt, aEndPt;
+ tools::Rectangle aStartRect, aEndRect;
+ uno::Reference<drawing::XShape> xStartSp, xEndSp;
+ uno::Reference<beans::XPropertySet> xPropSet(rXConnector, uno::UNO_QUERY);
+ xPropSet->getPropertyValue("EdgeStartPoint") >>= aStartPt;
+ xPropSet->getPropertyValue("EdgeEndPoint") >>= aEndPt;
+ xPropSet->getPropertyValue("StartShape") >>= xStartSp;
+ xPropSet->getPropertyValue("EndShape") >>= xEndSp;
+ xPropSet->setPropertyValue("EdgeNode1HorzDist", Any(sal_Int32(0)));
+ xPropSet->setPropertyValue("EdgeNode1VertDist", Any(sal_Int32(0)));
+ xPropSet->setPropertyValue("EdgeNode2HorzDist", Any(sal_Int32(0)));
+ xPropSet->setPropertyValue("EdgeNode2VertDist", Any(sal_Int32(0)));
+
+ SdrObject* pStartObj = xStartSp.is() ? SdrObject::getSdrObjectFromXShape(xStartSp) : nullptr;
+ SdrObject* pEndObj = xEndSp.is() ? SdrObject::getSdrObjectFromXShape(xEndSp) : nullptr;
+
+ sal_Int32 nStartSpLineW = 0;
+ sal_Int32 nStartA = -1;
+ sal_Int32 nEndA = -1;
+ if (pStartObj)
+ {
+ aStartRect = pStartObj->GetSnapRect();
+ uno::Reference<beans::XPropertySet> xPropxStartSp(xStartSp, uno::UNO_QUERY);
+ xPropxStartSp->getPropertyValue("LineWidth") >>= nStartSpLineW;
+ if (nStartSpLineW)
+ nStartSpLineW = nStartSpLineW / 2;
+ nStartA = lcl_GetAngle(xStartSp, aStartPt);
+ }
+ sal_Int32 nEndSpLineW = 0;
+ if (pEndObj)
+ {
+ aEndRect = pEndObj->GetSnapRect();
+ uno::Reference<beans::XPropertySet> xPropxEndSp(xEndSp, uno::UNO_QUERY);
+ xPropxEndSp->getPropertyValue("LineWidth") >>= nEndSpLineW;
+ if (nEndSpLineW)
+ nEndSpLineW = nEndSpLineW / 2;
+ nEndA = lcl_GetAngle(xEndSp, aEndPt);
+ }
+
+ const OUString sConnectorName = rShapePtr->getConnectorName();
+ if (sConnectorName == "bentConnector2")
+ {
+ awt::Size aConnSize = rXConnector->getSize();
+ if (xStartSp.is() || xEndSp.is())
+ {
+ if (nStartA >= 0)
+ {
+ switch (nStartA)
+ {
+ case 0: nEdge = aEndPt.X - aStartRect.Right(); break;
+ case 180: nEdge = aEndPt.X - aStartRect.Left(); break;
+ case 90: nEdge = aEndPt.Y - aStartRect.Bottom(); break;
+ case 270: nEdge = aEndPt.Y - aStartRect.Top(); break;
+ }
+ nEdge += nStartSpLineW * (nStartA >= 180 ? +1 : -1);
+ } else {
+ switch (nEndA)
+ {
+ case 0: nEdge = aStartPt.X - aEndRect.Right(); break;
+ case 180: nEdge = aStartPt.X - aEndRect.Left(); break;
+ case 90: nEdge = aStartPt.Y - aEndRect.Bottom(); break;
+ case 270: nEdge = aStartPt.Y - aEndRect.Top(); break;
+ }
+ nEdge += nEndSpLineW * (nEndA >= 180 ? +1 : -1);
+ }
+ }
+ else
+ {
+ bool bFlipH = rShapePtr->getFlipH();
+ bool bFlipV = rShapePtr->getFlipV();
+ sal_Int32 nConnectorAngle = rShapePtr->getRotation() / 60000;
+ if (aConnSize.Height < aConnSize.Width)
+ {
+ if ((nConnectorAngle == 90 && bFlipH && bFlipV) || (nConnectorAngle == 180)
+ || (nConnectorAngle == 270 && bFlipH))
+ nEdge -= aConnSize.Width;
+ else
+ nEdge += aConnSize.Width;
+ }
+ else
+ {
+ if ((nConnectorAngle == 180 && bFlipV) || (nConnectorAngle == 270 && bFlipV)
+ || (nConnectorAngle == 90 && bFlipH && bFlipV)
+ || (nConnectorAngle == 0 && !bFlipV))
+ nEdge -= aConnSize.Height;
+ else
+ nEdge += aConnSize.Height;
+ }
+ }
+ xPropSet->setPropertyValue("EdgeLine1Delta", Any(nEdge / 2));
+ }
+}
+
+// create connection between two shape with a connector shape.
+void SlidePersist::createConnectorShapeConnection()
+{
+ sal_Int32 nConnectorShapeCount = maConnectorShapeId.size();
+ for (sal_Int32 i = 0; i < nConnectorShapeCount; i++)
+ {
+ const auto& pIt = maShapeMap.find(maConnectorShapeId[i]);
+ if (pIt == maShapeMap.end())
+ continue;
+ oox::drawingml::ConnectorShapePropertiesList aConnectorShapeProperties
+ = pIt->second->getConnectorShapeProperties();
+ uno::Reference<drawing::XShape> xConnector(pIt->second->getXShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xPropertySet(xConnector, uno::UNO_QUERY);
+
+ if (xConnector.is())
+ {
+ sal_Int32 nCount = aConnectorShapeProperties.size();
+ for (sal_Int32 j = 0; j < nCount; j++)
+ {
+ OUString aDestShapeId = aConnectorShapeProperties[j].maDestShapeId;
+ const auto& pShape = maShapeMap.find(aDestShapeId);
+ if (pShape == maShapeMap.end())
+ continue;
+ uno::Reference<drawing::XShape> xShape(pShape->second->getXShape(), uno::UNO_QUERY);
+ if (xShape.is())
+ {
+ uno::Reference<drawing::XGluePointsSupplier> xSupplier(xShape, uno::UNO_QUERY);
+ css::uno::Reference<css::container::XIdentifierContainer> xGluePoints(
+ xSupplier->getGluePoints(), uno::UNO_QUERY);
+
+ sal_Int32 nCountGluePoints = xGluePoints->getIdentifiers().getLength();
+ sal_Int32 nGlueId = aConnectorShapeProperties[j].mnDestGlueId;
+
+ // The first 4 glue points belong to the bounding box.
+ if (nCountGluePoints > 4)
+ nGlueId += 4;
+ else
+ {
+ // change id of the left and right glue points of the bounding box (1 <-> 3)
+ if (nGlueId == 1)
+ nGlueId = 3; // Right
+ else if (nGlueId == 3)
+ nGlueId = 1; // Left
+ }
+
+ bool bStart = aConnectorShapeProperties[j].mbStartShape;
+ if (bStart)
+ {
+ xPropertySet->setPropertyValue("StartShape", uno::Any(xShape));
+ xPropertySet->setPropertyValue("StartGluePointIndex", uno::Any(nGlueId));
+ }
+ else
+ {
+ xPropertySet->setPropertyValue("EndShape", uno::Any(xShape));
+ xPropertySet->setPropertyValue("EndGluePointIndex", uno::Any(nGlueId));
+ }
+ }
+ }
+ uno::Reference<beans::XPropertySetInfo> xPropInfo = xPropertySet->getPropertySetInfo();
+ if (xPropInfo->hasPropertyByName("EdgeKind"))
+ {
+ ConnectorType aConnectorType;
+ xPropertySet->getPropertyValue("EdgeKind") >>= aConnectorType;
+ if (aConnectorType == ConnectorType_STANDARD)
+ lcl_SetEdgeLineValue(xConnector, pIt->second);
+ }
+ }
+ }
+ maConnectorShapeId.clear();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/slidetimingcontext.cxx b/oox/source/ppt/slidetimingcontext.cxx
new file mode 100644
index 000000000..300249446
--- /dev/null
+++ b/oox/source/ppt/slidetimingcontext.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/slidetimingcontext.hxx>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/ppt/timenodelistcontext.hxx>
+#include "buildlistcontext.hxx"
+#include <oox/token/namespaces.hxx>
+
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+SlideTimingContext::SlideTimingContext( FragmentHandler2 const & rParent, TimeNodePtrList & aTimeNodeList ) noexcept
+ : FragmentHandler2( rParent )
+ , maTimeNodeList( aTimeNodeList )
+{
+}
+
+SlideTimingContext::~SlideTimingContext() noexcept
+{
+
+}
+
+::oox::core::ContextHandlerRef SlideTimingContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( bldLst ):
+ return new BuildListContext( *this );
+ case PPT_TOKEN( extLst ):
+ return this;
+ case PPT_TOKEN( tnLst ):
+ // timing nodes
+ {
+ return new TimeNodeListContext( *this, maTimeNodeList );
+ }
+ break;
+
+ default:
+ return this;
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/slidetransition.cxx b/oox/source/ppt/slidetransition.cxx
new file mode 100644
index 000000000..5221c2f68
--- /dev/null
+++ b/oox/source/ppt/slidetransition.cxx
@@ -0,0 +1,467 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/slidetransition.hxx>
+
+#include <com/sun/star/animations/TransitionType.hpp>
+#include <com/sun/star/animations/TransitionSubType.hpp>
+#include <com/sun/star/animations/XTransitionFilter.hpp>
+
+#include <sal/log.hxx>
+#include <tools/color.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <oox/helper/propertymap.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/properties.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/ppt/pptfilterhelpers.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+
+namespace oox::ppt {
+
+ SlideTransition::SlideTransition()
+ : mnTransitionType( 0 )
+ , mnTransitionSubType( 0 )
+ , mbTransitionDirectionNormal( true )
+ , mnAnimationSpeed( AnimationSpeed_FAST )
+ , mfTransitionDurationInSeconds( -1.0 )
+ , mbMode( true )
+ , mnAdvanceTime( -1 )
+ , mnTransitionFadeColor( 0 )
+ {
+
+ }
+
+ SlideTransition::SlideTransition(std::u16string_view sFilterName)
+ : mnTransitionType( 0 )
+ , mnTransitionSubType( 0 )
+ , mbTransitionDirectionNormal( true )
+ , mnAnimationSpeed( AnimationSpeed_FAST )
+ , mfTransitionDurationInSeconds( -1.0 )
+ , mbMode( true )
+ , mnAdvanceTime( -1 )
+ , mnTransitionFadeColor( 0 )
+ {
+ const transition *p = transition::find( sFilterName );
+ if( p )
+ {
+ mnTransitionType = p->mnType;
+ mnTransitionSubType = p->mnSubType;
+ mbTransitionDirectionNormal = p->mbDirection;
+ }
+ }
+
+ void SlideTransition::setSlideProperties( PropertyMap & aProps )
+ {
+ try
+ {
+ aProps.setProperty( PROP_TransitionType, mnTransitionType);
+ aProps.setProperty( PROP_TransitionSubtype, mnTransitionSubType);
+ aProps.setProperty( PROP_TransitionDirection, mbTransitionDirectionNormal);
+ aProps.setProperty( PROP_Speed, mnAnimationSpeed);
+ if( mfTransitionDurationInSeconds >= 0.0 )
+ aProps.setProperty( PROP_TransitionDuration, mfTransitionDurationInSeconds);
+ aProps.setProperty( PROP_TransitionFadeColor, mnTransitionFadeColor);
+ if( mnAdvanceTime != -1 ) {
+ aProps.setProperty( PROP_Duration, mnAdvanceTime/1000);
+ aProps.setProperty( PROP_Change, static_cast<sal_Int32>(1));
+ }
+ }
+ catch( Exception& )
+ {
+ // should not happen
+ TOOLS_WARN_EXCEPTION( "oox", "" );
+ }
+ }
+
+ void SlideTransition::setTransitionFilterProperties( const Reference< XTransitionFilter > & xFilter )
+ {
+ try
+ {
+ xFilter->setTransition( mnTransitionType );
+ xFilter->setSubtype( mnTransitionSubType );
+ xFilter->setDirection( mbTransitionDirectionNormal );
+ xFilter->setFadeColor( 0 );
+ xFilter->setMode( mbMode );
+ }
+ catch( Exception& )
+ {
+ // should not happen
+ TOOLS_WARN_EXCEPTION( "oox", "" );
+ }
+ }
+
+ void SlideTransition::setOoxTransitionSpeed( sal_Int32 nToken)
+ {
+ switch( nToken )
+ {
+ /* the speed values are located in the PPT97 importer
+ * sd/source/filter/ppt/pptin.cxx:1783
+ * (void ImplSdPPTImport::ImportPageEffect)
+ */
+ case XML_fast:
+ mnAnimationSpeed = AnimationSpeed_FAST;
+ mfTransitionDurationInSeconds = 0.5;
+ break;
+ case XML_med:
+ mnAnimationSpeed = AnimationSpeed_MEDIUM;
+ mfTransitionDurationInSeconds = 0.75;
+ break;
+ case XML_slow:
+ mnAnimationSpeed = AnimationSpeed_SLOW;
+ mfTransitionDurationInSeconds = 1.0;
+ break;
+ default:
+ // should not happen. just ignore
+ break;
+ }
+ }
+
+ void SlideTransition::setOoxTransitionSpeed( double fDurationInSeconds )
+ {
+ // for compatibility
+ mnAnimationSpeed = ( fDurationInSeconds <= 0.5 ) ? AnimationSpeed_FAST
+ : ( fDurationInSeconds >= 1.0 ) ? AnimationSpeed_SLOW : AnimationSpeed_MEDIUM;
+ mfTransitionDurationInSeconds = fDurationInSeconds;
+ }
+
+ sal_Int16 SlideTransition::ooxToOdpEightDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ nOdpDirection = ooxToOdpBorderDirections( nOoxType );
+ if( nOdpDirection == 0 )
+ {
+ nOdpDirection = ooxToOdpCornerDirections( nOoxType );
+ }
+ return nOdpDirection;
+ }
+
+ sal_Int16 SlideTransition::ooxToOdpBorderDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ switch( nOoxType )
+ {
+ case XML_d:
+ nOdpDirection = TransitionSubType::FROMTOP;
+ break;
+ case XML_l:
+ nOdpDirection = TransitionSubType::FROMLEFT;
+ break;
+ case XML_r:
+ nOdpDirection = TransitionSubType::FROMRIGHT;
+ break;
+ case XML_u:
+ nOdpDirection = TransitionSubType::FROMBOTTOM;
+ break;
+ default:
+ nOdpDirection= 0;
+ break;
+ }
+ return nOdpDirection;
+ }
+
+ sal_Int16 SlideTransition::ooxToOdpSideDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ switch( nOoxType )
+ {
+ case XML_d:
+ case XML_u:
+ nOdpDirection = TransitionSubType::TOPTOBOTTOM;
+ break;
+ case XML_l:
+ case XML_r:
+ nOdpDirection = TransitionSubType::LEFTTORIGHT;
+ break;
+ default:
+ nOdpDirection= 0;
+ break;
+ }
+ return nOdpDirection;
+ }
+
+ bool SlideTransition::ooxToOdpSideDirectionsDirectionNormal( ::sal_Int32 nOoxType )
+ {
+ bool bOdpDirection = true;
+ switch( nOoxType )
+ {
+ case XML_u:
+ case XML_l:
+ bOdpDirection = false;
+ break;
+ }
+ return bOdpDirection;
+ }
+
+ sal_Int16 SlideTransition::ooxToOdpCornerDirections( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDirection;
+ switch( nOoxType )
+ {
+ case XML_lu:
+ nOdpDirection = TransitionSubType::FROMBOTTOMRIGHT;
+ break;
+ case XML_ru:
+ nOdpDirection = TransitionSubType::FROMBOTTOMLEFT;
+ break;
+ case XML_ld:
+ nOdpDirection = TransitionSubType::FROMTOPRIGHT;
+ break;
+ case XML_rd:
+ nOdpDirection = TransitionSubType::FROMTOPLEFT;
+ break;
+ default:
+ nOdpDirection = 0;
+ break;
+ }
+ return nOdpDirection;
+ }
+
+ sal_Int16 SlideTransition::ooxToOdpDirection( ::sal_Int32 nOoxType )
+ {
+ sal_Int16 nOdpDir;
+ switch( nOoxType )
+ {
+ case XML_vert:
+ nOdpDir = TransitionSubType::VERTICAL;
+ break;
+ case XML_horz:
+ nOdpDir = TransitionSubType::HORIZONTAL;
+ break;
+ default:
+ nOdpDir = 0;
+ break;
+ }
+ return nOdpDir;
+ }
+
+ void SlideTransition::setOoxTransitionType( ::sal_Int32 OoxType, ::sal_Int32 param1, ::sal_Int32 param2 )
+ {
+ switch( OoxType )
+ {
+ case PPT_TOKEN( blinds ):
+ mnTransitionType = TransitionType::BLINDSWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ break;
+ case PPT_TOKEN( checker ):
+ mnTransitionType = TransitionType::CHECKERBOARDWIPE;
+ switch ( param1 )
+ {
+ case XML_vert:
+ mnTransitionSubType = TransitionSubType::DOWN;
+ break;
+ case XML_horz:
+ mnTransitionSubType = TransitionSubType::ACROSS;
+ break;
+ default:
+ break;
+ }
+ break;
+ case PPT_TOKEN( comb ):
+ mnTransitionType = TransitionType::PUSHWIPE;
+ switch( param1 )
+ {
+ case XML_vert:
+ mnTransitionSubType = TransitionSubType::COMBVERTICAL;
+ break;
+ case XML_horz:
+ mnTransitionSubType = TransitionSubType::COMBHORIZONTAL;
+ break;
+ default:
+ break;
+ }
+ break;
+ case PPT_TOKEN( cover ):
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpEightDirections( param1 );
+ break;
+ case PPT_TOKEN( pull ): // uncover
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpEightDirections( param1 );
+ mbTransitionDirectionNormal = false;
+ break;
+ case PPT_TOKEN( cut ):
+ if( param1 )
+ {
+ mnTransitionType = TransitionType::BARWIPE;
+ mnTransitionSubType = TransitionSubType::FADEOVERCOLOR;
+ }
+ SAL_WARN("oox.ppt", "OOX: cut transition fallback." );
+ break;
+ case PPT_TOKEN( fade ):
+ mnTransitionType = TransitionType::FADE;
+ if( param1 )
+ {
+ mnTransitionSubType = TransitionSubType::FADEOVERCOLOR;
+ }
+ else
+ {
+ mnTransitionSubType = TransitionSubType::CROSSFADE;
+ }
+ break;
+ case PPT_TOKEN( push ):
+ mnTransitionType = TransitionType::PUSHWIPE;
+ mnTransitionSubType = ooxToOdpBorderDirections( param1 );
+ break;
+ case PPT_TOKEN( wipe ):
+ mnTransitionType = TransitionType::BARWIPE;
+ mnTransitionSubType = ooxToOdpSideDirections( param1 );
+ mbTransitionDirectionNormal = ooxToOdpSideDirectionsDirectionNormal( param1 );
+ break;
+ case PPT_TOKEN( split ):
+ mnTransitionType = TransitionType::BARNDOORWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ if( param2 == XML_in )
+ {
+ // reverse
+ mbTransitionDirectionNormal = false;
+ }
+ break;
+ case PPT_TOKEN( wheel ):
+ mnTransitionType = TransitionType::PINWHEELWIPE;
+ switch( param1 )
+ {
+ case 1:
+ mnTransitionSubType = TransitionSubType::ONEBLADE;
+ break;
+ case 2:
+ mnTransitionSubType = TransitionSubType::TWOBLADEVERTICAL;
+ break;
+ case 3:
+ mnTransitionSubType = TransitionSubType::THREEBLADE;
+ break;
+ case 4:
+ mnTransitionSubType = TransitionSubType::FOURBLADE;
+ break;
+ case 8:
+ mnTransitionSubType = TransitionSubType::EIGHTBLADE;
+ break;
+ default:
+ SAL_INFO(
+ "oox.ppt",
+ "strange number of blades for the wheel-wipe " << param1);
+ if( param1 > 8 )
+ {
+ mnTransitionSubType = TransitionSubType::EIGHTBLADE;
+ }
+ else if( param1 > 4 )
+ {
+ mnTransitionSubType = TransitionSubType::FOURBLADE;
+ }
+ else if( param1 == 0)
+ {
+ mnTransitionSubType = TransitionSubType::ONEBLADE;
+ }
+ break;
+ }
+ break;
+ case PPT_TOKEN( randomBar ):
+ mnTransitionType = TransitionType::RANDOMBARWIPE;
+ mnTransitionSubType = ooxToOdpDirection( param1 );
+ break;
+ case PPT_TOKEN( circle ):
+ mnTransitionType = TransitionType::ELLIPSEWIPE;
+ mnTransitionSubType = TransitionSubType::CIRCLE;
+ break;
+ case PPT_TOKEN( diamond ):
+ mnTransitionType = TransitionType::IRISWIPE;
+ mnTransitionSubType = TransitionSubType::DIAMOND;
+ break;
+ case PPT_TOKEN( dissolve ):
+ mnTransitionType = TransitionType::DISSOLVE;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case PPT_TOKEN( newsflash ):
+ mnTransitionType = TransitionType::ZOOM;
+ mnTransitionSubType = TransitionSubType::ROTATEIN;
+ break;
+ case PPT_TOKEN( plus ):
+ mnTransitionType = TransitionType::FOURBOXWIPE;
+ mnTransitionSubType = TransitionSubType::CORNERSOUT;
+ break;
+ case PPT_TOKEN( random ):
+ mnTransitionType = TransitionType::RANDOM;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case PPT_TOKEN( wedge ):
+ mnTransitionType = TransitionType::FANWIPE;
+ mnTransitionSubType = TransitionSubType::CENTERTOP;
+ break;
+ case PPT_TOKEN( zoom ):
+ mnTransitionType = TransitionType::ZOOM;
+ mnTransitionSubType = TransitionSubType::DEFAULT;
+ break;
+ case P14_TOKEN(prism):
+ mnTransitionType = TransitionType::MISCSHAPEWIPE;
+ if (param1)
+ mnTransitionSubType = TransitionSubType::CORNERSIN;
+ else
+ mnTransitionSubType = TransitionSubType::CORNERSOUT;
+ break;
+ case P14_TOKEN(vortex):
+ mnTransitionType = TransitionType::MISCSHAPEWIPE;
+ mnTransitionSubType = TransitionSubType::VERTICAL;
+ break;
+ case P14_TOKEN(ripple):
+ mnTransitionType = TransitionType::MISCSHAPEWIPE;
+ mnTransitionSubType = TransitionSubType::HORIZONTAL;
+ break;
+ case P14_TOKEN(glitter):
+ mnTransitionType = TransitionType::MISCSHAPEWIPE;
+ mnTransitionSubType = TransitionSubType::DIAMOND;
+ break;
+ case P14_TOKEN(honeycomb):
+ mnTransitionType = TransitionType::MISCSHAPEWIPE;
+ mnTransitionSubType = TransitionSubType::HEART;
+ break;
+ case P14_TOKEN(flash):
+ mnTransitionType = TransitionType::FADE;
+ mnTransitionSubType = TransitionSubType::FADEOVERCOLOR;
+ mnTransitionFadeColor = static_cast<sal_Int32>(COL_WHITE);
+ break;
+ case PPT_TOKEN(strips):
+ mnTransitionType = TransitionType::SLIDEWIPE;
+ mnTransitionSubType = ooxToOdpCornerDirections( param1 );
+ break;
+ default:
+ mnTransitionType = 0;
+ break;
+ }
+ }
+
+ void SlideTransition::setPresetTransition(std::u16string_view sPresetTransition)
+ {
+ if (sPresetTransition == u"fallOver")
+ {
+ mnTransitionType = TransitionType::MISCSHAPEWIPE;
+ mnTransitionSubType = TransitionSubType::LEFTTORIGHT;
+ }
+ else
+ {
+ mnTransitionType = 0;
+ }
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/slidetransitioncontext.cxx b/oox/source/ppt/slidetransitioncontext.cxx
new file mode 100644
index 000000000..8ec8e0fd8
--- /dev/null
+++ b/oox/source/ppt/slidetransitioncontext.cxx
@@ -0,0 +1,200 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/slidetransitioncontext.hxx>
+
+#include <oox/ppt/backgroundproperties.hxx>
+#include <oox/ppt/soundactioncontext.hxx>
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+SlideTransitionContext::SlideTransitionContext( FragmentHandler2 const & rParent, const AttributeList& rAttribs, PropertyMap & aProperties ) noexcept
+: FragmentHandler2( rParent )
+, maSlideProperties( aProperties )
+, mbHasTransition( false )
+, mbHasTransitionDuration( false )
+{
+ // ST_TransitionSpeed
+ maTransition.setOoxTransitionSpeed( rAttribs.getToken( XML_spd, XML_fast ) );
+
+ // p14:dur
+ sal_Int32 nDurationInMs = rAttribs.getInteger( P14_TOKEN( dur ), -1 );
+ if( nDurationInMs > -1 )
+ {
+ // In MSO 0 is visible as 0.01s
+ if( nDurationInMs == 0.0 )
+ nDurationInMs = 10;
+ maTransition.setOoxTransitionSpeed( nDurationInMs / 1000.0 );
+ mbHasTransitionDuration = true;
+ }
+
+ // TODO
+ rAttribs.getBool( XML_advClick, true );
+
+ // careful. if missing, no auto advance... 0 looks like a valid value
+ // for auto advance
+ if(rAttribs.hasAttribute( XML_advTm ))
+ maTransition.setOoxAdvanceTime( rAttribs.getInteger( XML_advTm, -1 ) );
+}
+
+SlideTransitionContext::~SlideTransitionContext() noexcept
+{
+
+}
+
+::oox::core::ContextHandlerRef SlideTransitionContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+{
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( blinds ):
+ case PPT_TOKEN( checker ):
+ case PPT_TOKEN( comb ):
+ case PPT_TOKEN( randomBar ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getToken( XML_dir, XML_horz ), 0);
+ }
+ return this;
+ case PPT_TOKEN( cover ):
+ case PPT_TOKEN( pull ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getToken( XML_dir, XML_l ), 0 );
+ }
+ return this;
+ case PPT_TOKEN( cut ):
+ case PPT_TOKEN( fade ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, sal_Int32(rAttribs.getBool( XML_thruBlk, false )), 0);
+ }
+ return this;
+ case PPT_TOKEN( push ):
+ case PPT_TOKEN( wipe ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getToken( XML_dir, XML_l ), 0 );
+ }
+ return this;
+ case PPT_TOKEN( split ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getToken( XML_orient, XML_horz ), rAttribs.getToken( XML_dir, XML_out ) );
+ }
+ return this;
+ case PPT_TOKEN( zoom ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getToken( XML_dir, XML_out ), 0 );
+ }
+ return this;
+ case PPT_TOKEN( wheel ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getUnsigned( XML_spokes, 4 ), 0 );
+ // unsignedInt
+ }
+ return this;
+ case PPT_TOKEN( circle ):
+ case PPT_TOKEN( diamond ):
+ case PPT_TOKEN( dissolve ):
+ case PPT_TOKEN( newsflash ):
+ case PPT_TOKEN( plus ):
+ case PPT_TOKEN( random ):
+ case PPT_TOKEN( wedge ):
+ case P14_TOKEN( vortex ):
+ case P14_TOKEN( ripple ):
+ case P14_TOKEN( glitter ):
+ case P14_TOKEN( honeycomb ):
+ case P14_TOKEN( flash ):
+ // CT_Empty
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, 0, 0 );
+ }
+ return this;
+
+ case PPT_TOKEN( sndAc ): // CT_TransitionSoundAction
+ //"Sound"
+ return new SoundActionContext ( *this, maSlideProperties );
+ case PPT_TOKEN( extLst ): // CT_OfficeArtExtensionList
+ return this;
+
+ case P14_TOKEN(prism):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType(aElementToken, sal_Int32(rAttribs.getBool(XML_isInverted, false)), 0);
+ }
+ return this;
+ case P15_TOKEN(prstTrans):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setPresetTransition(rAttribs.getString(XML_prst, ""));
+ }
+ return this;
+ case PPT_TOKEN( strips ):
+ if (!mbHasTransition)
+ {
+ mbHasTransition = true;
+ maTransition.setOoxTransitionType( aElementToken, rAttribs.getToken( XML_dir, XML_ld ), 0 );
+ }
+ return this;
+
+
+ default:
+ break;
+ }
+
+ return this;
+}
+
+void SlideTransitionContext::onEndElement()
+{
+ if( isCurrentElement(PPT_TOKEN( transition )) )
+ {
+ if( mbHasTransition || mbHasTransitionDuration )
+ {
+ maTransition.setSlideProperties( maSlideProperties );
+ mbHasTransition = false;
+ }
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/soundactioncontext.cxx b/oox/source/ppt/soundactioncontext.cxx
new file mode 100644
index 000000000..bac5c6641
--- /dev/null
+++ b/oox/source/ppt/soundactioncontext.cxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <oox/ppt/soundactioncontext.hxx>
+
+#include <com/sun/star/io/XInputStream.hpp>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/helper/propertymap.hxx>
+#include <drawingml/embeddedwavaudiofile.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/properties.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <avmedia/mediaitem.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::com::sun::star::uno;
+
+namespace oox::ppt {
+
+ SoundActionContext::SoundActionContext( FragmentHandler2 const & rParent, PropertyMap & aProperties ) noexcept
+ : FragmentHandler2( rParent )
+ , maSlideProperties( aProperties )
+ , mbHasStartSound( false )
+ , mbLoopSound( false )
+ , mbStopSound( false )
+ {
+ }
+
+ SoundActionContext::~SoundActionContext() noexcept
+ {
+ }
+
+ void SoundActionContext::onEndElement()
+ {
+ if ( !isCurrentElement( PPT_TOKEN( sndAc ) ) )
+ return;
+
+ if( !mbHasStartSound )
+ return;
+
+ OUString url;
+#if HAVE_FEATURE_AVMEDIA
+ if ( !msSndName.isEmpty() )
+ {
+ Reference<css::io::XInputStream>
+ xInputStream = getFilter().openInputStream(msSndName);
+ if (xInputStream.is())
+ {
+ ::avmedia::EmbedMedia(getFilter().getModel(), msSndName, url, xInputStream);
+ xInputStream->closeInput();
+ }
+ }
+#endif
+ if ( !url.isEmpty() )
+ {
+ maSlideProperties.setProperty( PROP_Sound, url);
+ maSlideProperties.setProperty( PROP_SoundOn, true);
+ }
+ }
+
+ ::oox::core::ContextHandlerRef SoundActionContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( snd ):
+ if( mbHasStartSound )
+ {
+ msSndName = drawingml::getEmbeddedWAVAudioFile( getRelations(), rAttribs );
+ }
+ return this;
+ case PPT_TOKEN( endSnd ):
+ // CT_Empty
+ mbStopSound = true;
+ return this;
+ case PPT_TOKEN( stSnd ):
+ mbHasStartSound = true;
+ mbLoopSound = rAttribs.getBool( XML_loop, false );
+ return this;
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/timeanimvaluecontext.cxx b/oox/source/ppt/timeanimvaluecontext.cxx
new file mode 100644
index 000000000..e81f4967a
--- /dev/null
+++ b/oox/source/ppt/timeanimvaluecontext.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "timeanimvaluecontext.hxx"
+
+#include "animvariantcontext.hxx"
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+
+namespace oox::ppt {
+
+ TimeAnimValueListContext::TimeAnimValueListContext( FragmentHandler2 const & rParent,
+ TimeAnimationValueList & aTavList )
+ : FragmentHandler2( rParent )
+ , maTavList( aTavList )
+ , mbInValue( false )
+ {
+ }
+
+ TimeAnimValueListContext::~TimeAnimValueListContext( )
+ {
+ }
+
+ void TimeAnimValueListContext::onEndElement()
+ {
+ if( isCurrentElement( PPT_TOKEN( tav ) ) )
+ {
+ mbInValue = false;
+ }
+ }
+
+ ::oox::core::ContextHandlerRef TimeAnimValueListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( tav ):
+ {
+ mbInValue = true;
+ TimeAnimationValue val;
+ val.msFormula = rAttribs.getString( XML_fmla, OUString() );
+ val.msTime = rAttribs.getString( XML_tm, OUString() );
+ maTavList.push_back( val );
+ return this;
+ }
+ case PPT_TOKEN( val ):
+ if( mbInValue )
+ {
+ // CT_TLAnimVariant
+ return new AnimVariantContext( *this, aElementToken, maTavList.back().maValue );
+ }
+ break;
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/timeanimvaluecontext.hxx b/oox/source/ppt/timeanimvaluecontext.hxx
new file mode 100644
index 000000000..34b1c5432
--- /dev/null
+++ b/oox/source/ppt/timeanimvaluecontext.hxx
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_TIMEANIMVALUECONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_TIMEANIMVALUECONTEXT_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/ppt/animationspersist.hxx>
+
+namespace oox::ppt {
+
+ /** CT_TLTimeAnimateValueList */
+ class TimeAnimValueListContext
+ : public ::oox::core::FragmentHandler2
+ {
+ public:
+ TimeAnimValueListContext( ::oox::core::FragmentHandler2 const & rParent,
+ TimeAnimationValueList & aTavList );
+
+ virtual ~TimeAnimValueListContext( ) override;
+
+ virtual void onEndElement() override;
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ TimeAnimationValueList & maTavList;
+ bool mbInValue;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/timenode.cxx b/oox/source/ppt/timenode.cxx
new file mode 100644
index 000000000..2701a3f60
--- /dev/null
+++ b/oox/source/ppt/timenode.cxx
@@ -0,0 +1,668 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/timenode.hxx>
+
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/animations/XAnimateColor.hpp>
+#include <com/sun/star/animations/XAnimateMotion.hpp>
+#include <com/sun/star/animations/XAnimateTransform.hpp>
+#include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/animations/XAudio.hpp>
+#include <com/sun/star/animations/XIterateContainer.hpp>
+#include <com/sun/star/animations/XTimeContainer.hpp>
+#include <com/sun/star/animations/XTransitionFilter.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/Event.hpp>
+#include <com/sun/star/animations/EventTrigger.hpp>
+#include <com/sun/star/io/WrongFormatException.hpp>
+#include <com/sun/star/presentation/EffectNodeType.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <oox/core/xmlfilterbase.hxx>
+#include <oox/ppt/pptfilterhelpers.hxx>
+#include <oox/token/tokens.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::oox::core;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+
+namespace {
+
+void lcl_setAncestorSubItem( const Reference<XAnimationNode>& xParent, sal_Int16 nSubItem )
+{
+
+ Reference<XAnimationNode> xNode = xParent;
+
+ while ( xNode.is() )
+ {
+ if ( xNode->getType() == AnimationNodeType::ANIMATE )
+ {
+ Reference<XAnimate> xAnimate( xNode, UNO_QUERY );
+ if ( xAnimate.is() )
+ xAnimate->setSubItem( nSubItem );
+ break;
+ }
+ else if ( xNode->getType() == AnimationNodeType::ITERATE )
+ {
+ Reference<XIterateContainer> xIterateContainer( xNode, UNO_QUERY );
+ if ( xIterateContainer.is() )
+ xIterateContainer->setSubItem( nSubItem );
+ break;
+ }
+
+ xNode.set( xNode->getParent(), UNO_QUERY );
+ }
+}
+
+}
+
+namespace oox::ppt {
+ OUString TimeNode::getServiceName( sal_Int16 nNodeType )
+ {
+ OUString sServiceName;
+ switch( nNodeType )
+ {
+ case AnimationNodeType::PAR:
+ sServiceName = "com.sun.star.animations.ParallelTimeContainer";
+ break;
+ case AnimationNodeType::SEQ:
+ sServiceName = "com.sun.star.animations.SequenceTimeContainer";
+ break;
+ case AnimationNodeType::ANIMATE:
+ sServiceName = "com.sun.star.animations.Animate";
+ break;
+ case AnimationNodeType::ITERATE:
+ sServiceName = "com.sun.star.animations.IterateContainer";
+ break;
+ case AnimationNodeType::ANIMATECOLOR:
+ sServiceName = "com.sun.star.animations.AnimateColor";
+ break;
+ case AnimationNodeType::TRANSITIONFILTER:
+ sServiceName = "com.sun.star.animations.TransitionFilter";
+ break;
+ case AnimationNodeType::ANIMATEMOTION:
+ sServiceName = "com.sun.star.animations.AnimateMotion";
+ break;
+ case AnimationNodeType::ANIMATETRANSFORM:
+ sServiceName = "com.sun.star.animations.AnimateTransform";
+ break;
+ case AnimationNodeType::COMMAND:
+ sServiceName = "com.sun.star.animations.Command";
+ break;
+ case AnimationNodeType::SET:
+ sServiceName = "com.sun.star.animations.AnimateSet";
+ break;
+ case AnimationNodeType::AUDIO:
+ sServiceName = "com.sun.star.animations.Audio";
+ break;
+ default:
+ SAL_INFO("oox.ppt","OOX: unhandled type " << nNodeType );
+ break;
+ }
+ return sServiceName;
+ }
+
+ TimeNode::TimeNode( sal_Int16 nNodeType )
+ : mnNodeType( nNodeType )
+ , mbHasEndSyncValue( false )
+ {
+ }
+
+ TimeNode::~TimeNode()
+ {
+ }
+
+ void fixMainSequenceTiming( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
+ {
+ try
+ {
+ bool bFirst = true;
+ Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_SET_THROW );
+ while( xE->hasMoreElements() )
+ {
+ // click node
+ Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
+
+ Event aEvent;
+ aEvent.Trigger = EventTrigger::ON_NEXT;
+ aEvent.Repeat = 0;
+ xClickNode->setBegin( Any( aEvent ) );
+
+ if( bFirst )
+ {
+ bFirst = false;
+ Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_SET_THROW );
+ if( xE2->hasMoreElements() )
+ {
+ // with node
+ xE2->nextElement() >>= xEA2;
+ if( xEA2.is() )
+ xE2 = xEA2->createEnumeration();
+ else
+ xE2.clear();
+
+ if( xE2.is() && xE2->hasMoreElements() )
+ {
+ Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
+ const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
+ for( const NamedValue& rProp : aUserData )
+ {
+ if ( rProp.Name == "node-type" )
+ {
+ sal_Int16 nNodeType = 0;
+ rProp.Value >>= nNodeType;
+ if( nNodeType != css::presentation::EffectNodeType::ON_CLICK )
+ {
+ // first effect does not start on click, so correct
+ // first click nodes begin to 0s
+ xClickNode->setBegin( Any( 0.0 ) );
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch( Exception& )
+ {
+ SAL_INFO("oox.ppt","fixMainSequenceTiming(), exception caught!" );
+ }
+ }
+
+ void fixInteractiveSequenceTiming( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
+ {
+ try
+ {
+ Any aBegin( xNode->getBegin() );
+ Any aEmpty;
+ xNode->setBegin( aEmpty );
+
+ Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
+ Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_SET_THROW );
+ while( xE->hasMoreElements() )
+ {
+ // click node
+ Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
+ xClickNode->setBegin( aBegin );
+ }
+ }
+ catch( Exception& )
+ {
+ SAL_INFO("oox.ppt","fixInteractiveSequenceTiming(), exception caught!" );
+ }
+ }
+
+ void TimeNode::addNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
+ {
+ try {
+ sal_Int16 nNodeType = mnNodeType;
+
+ if (mnNodeType == AnimationNodeType::PAR && maNodeProperties[NP_ITERATETYPE].hasValue())
+ nNodeType = AnimationNodeType::ITERATE;
+
+ OUString sServiceName = getServiceName(nNodeType);
+
+ Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode );
+ if (!xNode)
+ return;
+ setNode(rFilter, xNode, pSlide, rxNode);
+ }
+ catch( const Exception& )
+ {
+ TOOLS_INFO_EXCEPTION("oox.ppt","OOX: exception raised in TimeNode::addNode()" );
+ }
+ }
+
+ void TimeNode::setNode(const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide, const Reference<XAnimationNode>& xParent)
+ {
+ SAL_WARN_IF( !xNode.is(), "oox.ppt", "null node passed" );
+
+ try {
+ if( !msId.isEmpty() )
+ {
+ pSlide->getAnimNodesMap()[ msId ] = xNode;
+ }
+
+ if( mpTarget )
+ {
+ sal_Int16 nSubItem(0);
+ maNodeProperties[ NP_TARGET ] = mpTarget->convert( pSlide, nSubItem );
+ if( mpTarget->mnType == XML_spTgt )
+ {
+ if ( xNode->getType() == AnimationNodeType::ANIMATE ||
+ xNode->getType() == AnimationNodeType::ITERATE )
+ {
+ maNodeProperties[ NP_SUBITEM ] <<= nSubItem;
+ }
+ else
+ lcl_setAncestorSubItem( xParent, nSubItem );
+ }
+ }
+
+ if( !maStCondList.empty() )
+ {
+ Any aAny = AnimationCondition::convertList( pSlide, maStCondList );
+ if( aAny.hasValue() )
+ {
+ xNode->setBegin( aAny );
+ }
+
+ }
+ if( !maEndCondList.empty() )
+ {
+ Any aAny = AnimationCondition::convertList( pSlide, maEndCondList );
+ if( aAny.hasValue() )
+ {
+ xNode->setEnd( aAny );
+ }
+ }
+ if( mbHasEndSyncValue )
+ {
+ Any aValue = maEndSyncValue.convert( pSlide );
+ xNode->setEndSync(aValue);
+ }
+
+ if( !maUserData.empty() )
+ {
+ Sequence< NamedValue > aUserDataSeq( static_cast< sal_Int32 >( maUserData.size() ) );
+ NamedValue* pValues = aUserDataSeq.getArray();
+ for (auto const& elem : maUserData)
+ {
+ pValues->Name = elem.first;
+ pValues->Value = elem.second;
+ ++pValues;
+ }
+ maNodeProperties[ NP_USERDATA ] <<= aUserDataSeq;
+ }
+
+ Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
+ Reference< XAnimateColor > xAnimateColor( xNode, UNO_QUERY );
+ Reference< XAnimateMotion > xAnimateMotion( xNode, UNO_QUERY );
+ Reference< XAnimateTransform > xAnimateTransform( xNode, UNO_QUERY );
+ Reference< XCommand > xCommand( xNode, UNO_QUERY );
+ Reference< XAudio > xAudio( xNode, UNO_QUERY );
+ Reference< XIterateContainer > xIterateContainer( xNode, UNO_QUERY );
+ sal_Int16 nInt16 = 0;
+ bool bBool = false;
+ double fDouble = 0;
+ OUString sString;
+ Sequence< NamedValue > aSeq;
+
+ for( int i = 0; i < NP_SIZE_; i++)
+ {
+ Any & aValue( maNodeProperties[ i ] );
+ if( aValue.hasValue() )
+ {
+ switch( i )
+ {
+ case NP_TO:
+ if( xAnimate.is() )
+ xAnimate->setTo( aValue );
+ break;
+ case NP_FROM:
+ if( xAnimate.is() )
+ xAnimate->setFrom( aValue );
+ break;
+ case NP_BY:
+ if( xAnimate.is() )
+ xAnimate->setBy( aValue );
+ break;
+ case NP_HIDEDURINGSHOW:
+ if (xAudio.is() && (aValue >>= bBool))
+ {
+ xAudio->setHideDuringShow(bBool);
+ }
+ break;
+ case NP_ISNARRATION:
+ if (xAudio.is() && (aValue >>= bBool))
+ {
+ xAudio->setNarration(bBool);
+ }
+ break;
+ case NP_TARGET:
+
+ if (xParent.is() && xParent->getType() == AnimationNodeType::ITERATE)
+ {
+ Reference<XIterateContainer> xParentContainer(xParent, UNO_QUERY);
+ if (xParentContainer.is())
+ xParentContainer->setTarget(aValue);
+ }
+ else
+ {
+ if (xAnimate.is())
+ xAnimate->setTarget(aValue);
+ if (xCommand.is())
+ xCommand->setTarget(aValue);
+ if (xAudio.is())
+ xAudio->setSource(aValue);
+ }
+ break;
+ case NP_SUBITEM:
+ if( aValue >>= nInt16 )
+ {
+ if( xAnimate.is() )
+ {
+ xAnimate->setSubItem( nInt16 );
+ }
+ else if ( xIterateContainer.is() )
+ {
+ xIterateContainer->setSubItem( nInt16 );
+ }
+ }
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_ATTRIBUTENAME:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= sString )
+ xAnimate->setAttributeName( sString );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_CALCMODE:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimate->setCalcMode( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_KEYTIMES:
+ if( xAnimate.is() )
+ {
+ Sequence<double> aKeyTimes;
+ if( aValue >>= aKeyTimes )
+ xAnimate->setKeyTimes(aKeyTimes);
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_VALUES:
+ if( xAnimate.is() )
+ {
+ Sequence<Any> aValues;
+ if( aValue >>= aValues )
+ xAnimate->setValues(aValues);
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_FORMULA:
+ if( xAnimate.is() )
+ {
+ if( aValue >>= sString )
+ xAnimate->setFormula(sString);
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_COLORINTERPOLATION:
+ if( xAnimateColor.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimateColor->setColorInterpolation( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_DIRECTION:
+ if( xAnimateColor.is() )
+ {
+ if( aValue >>= bBool )
+ xAnimateColor->setDirection( bBool );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_PATH:
+ if( xAnimateMotion.is() )
+ xAnimateMotion->setPath( aValue );
+ break;
+ case NP_TRANSFORMTYPE:
+ if( xAnimateTransform.is() )
+ {
+ if( aValue >>= nInt16 )
+ xAnimateTransform->setTransformType( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_USERDATA:
+ if( aValue >>= aSeq )
+ xNode->setUserData( aSeq );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_ACCELERATION:
+ if( aValue >>= fDouble )
+ xNode->setAcceleration( fDouble );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_DECELERATE:
+ if( aValue >>= fDouble )
+ xNode->setDecelerate( fDouble );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_AUTOREVERSE:
+ if( aValue >>= bBool )
+ xNode->setAutoReverse( bBool );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_DURATION:
+ xNode->setDuration( aValue );
+ break;
+ case NP_FILL:
+ if( aValue >>= nInt16 )
+ xNode->setFill( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_REPEATCOUNT:
+ xNode->setRepeatCount( aValue );
+ break;
+ case NP_REPEATDURATION:
+ xNode->setRepeatDuration( aValue );
+ break;
+ case NP_RESTART:
+ if( aValue >>= nInt16 )
+ xNode->setRestart( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ break;
+ case NP_COMMAND:
+ if( xCommand.is() )
+ {
+ if( aValue >>= nInt16 )
+ xCommand->setCommand( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_PARAMETER:
+ if( xCommand.is() )
+ xCommand->setParameter( aValue );
+ break;
+ case NP_ITERATETYPE:
+ if( xIterateContainer.is() )
+ {
+ if( aValue >>= nInt16 )
+ xIterateContainer->setIterateType( nInt16 );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ case NP_ITERATEINTERVAL:
+ if( xIterateContainer.is() )
+ {
+ if( aValue >>= fDouble )
+ xIterateContainer->setIterateInterval( fDouble );
+ else
+ {
+ SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
+ }
+ }
+ break;
+ default:
+ SAL_INFO("oox.ppt","ERR-OOX: unknown prop index " << i );
+ break;
+ }
+ }
+ }
+
+ if (xAnimate.is() && xAnimate->getValues().getLength() != xAnimate->getKeyTimes().getLength())
+ throw css::io::WrongFormatException();
+
+ if( mnNodeType == AnimationNodeType::TRANSITIONFILTER )
+ {
+
+ Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
+ maTransitionFilter.setTransitionFilterProperties( xFilter );
+ }
+
+ std::for_each(
+ maChildren.begin(), maChildren.end(),
+ [&rFilter, &xNode, &pSlide] (TimeNodePtr const & child) {
+ child->addNode(rFilter, xNode, pSlide);
+ } );
+
+ switch( mnNodeType )
+ {
+ case AnimationNodeType::SEQ:
+ {
+ sal_Int16 nEnum = 0;
+ if( maUserData[ "node-type" ] >>= nEnum )
+ {
+ if( nEnum == EffectNodeType::MAIN_SEQUENCE )
+ {
+ fixMainSequenceTiming( xNode );
+ }
+ else if( nEnum == EffectNodeType::INTERACTIVE_SEQUENCE )
+ {
+ fixInteractiveSequenceTiming( xNode );
+ }
+ }
+ break;
+ }
+ case AnimationNodeType::PAR:
+ // some other cut&paste... from AnimationImporter::importAnimationContainer()
+ break;
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_INFO_EXCEPTION("oox.ppt","OOX: exception raised in TimeNode::setNode()");
+ }
+ }
+
+ Reference< XAnimationNode > TimeNode::createAndInsert(
+ const XmlFilterBase& rFilter,
+ const OUString& rServiceName,
+ const Reference< XAnimationNode >& rxNode )
+ {
+ try {
+ Reference< XAnimationNode > xNode( Reference<css::lang::XMultiServiceFactory>(rFilter.getComponentContext()->getServiceManager(), UNO_QUERY_THROW)->createInstance( rServiceName ), UNO_QUERY_THROW );
+ Reference< XTimeContainer > xParentContainer( rxNode, UNO_QUERY_THROW );
+
+ xParentContainer->appendChild( xNode );
+ return xNode;
+ }
+ catch( const Exception& )
+ {
+ TOOLS_INFO_EXCEPTION("oox.ppt", "OOX: exception raised in TimeNode::createAndInsert() trying to create a service " << rServiceName);
+ }
+
+ return Reference< XAnimationNode >();
+ }
+
+ void TimeNode::setId( sal_Int32 nId )
+ {
+ msId = OUString::number(nId);
+ }
+
+ void TimeNode::setTo( const Any & aTo )
+ {
+ maNodeProperties[ NP_TO ] = aTo;
+ }
+
+ void TimeNode::setFrom( const Any & aFrom )
+ {
+ maNodeProperties[ NP_FROM ] = aFrom;
+ }
+
+ void TimeNode::setBy( const Any & aBy )
+ {
+ maNodeProperties[ NP_BY ] = aBy;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/timenodelistcontext.cxx b/oox/source/ppt/timenodelistcontext.cxx
new file mode 100644
index 000000000..a7637432a
--- /dev/null
+++ b/oox/source/ppt/timenodelistcontext.cxx
@@ -0,0 +1,1048 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <oox/ppt/timenodelistcontext.hxx>
+
+#include <rtl/math.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <com/sun/star/animations/AnimationTransformType.hpp>
+#include <com/sun/star/animations/AnimationCalcMode.hpp>
+#include <com/sun/star/animations/AnimationColorSpace.hpp>
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/ValuePair.hpp>
+#include <com/sun/star/presentation/EffectCommands.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+
+#include <oox/helper/attributelist.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <oox/drawingml/drawingmltypes.hxx>
+#include <drawingml/colorchoicecontext.hxx>
+#include <oox/ppt/slidetransition.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+#include <o3tl/string_view.hxx>
+
+#include "animvariantcontext.hxx"
+#include "commonbehaviorcontext.hxx"
+#include "conditioncontext.hxx"
+#include "commontimenodecontext.hxx"
+#include "timeanimvaluecontext.hxx"
+#include "animationtypes.hxx"
+#include "timetargetelementcontext.hxx"
+
+using namespace ::oox::core;
+using namespace ::oox::drawingml;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::xml::sax;
+using ::com::sun::star::beans::NamedValue;
+
+namespace {
+
+ oox::ppt::AnimationAttributeEnum getAttributeEnumByAPIName(std::u16string_view rAPIName)
+ {
+ oox::ppt::AnimationAttributeEnum eResult = oox::ppt::AnimationAttributeEnum::UNKNOWN;
+ const oox::ppt::ImplAttributeNameConversion *attrConv = oox::ppt::getAttributeConversionList();
+ while(attrConv->mpAPIName != nullptr)
+ {
+ if(o3tl::equalsAscii(rAPIName, attrConv->mpAPIName))
+ {
+ eResult = attrConv->meAttribute;
+ break;
+ }
+ attrConv++;
+ }
+ return eResult;
+ }
+
+ bool convertAnimationValueWithTimeNode(const oox::ppt::TimeNodePtr& pNode, css::uno::Any &rAny)
+ {
+ css::uno::Any aAny = pNode->getNodeProperties()[oox::ppt::NP_ATTRIBUTENAME];
+ OUString aNameList;
+ aAny >>= aNameList;
+
+ // only get first token.
+ return oox::ppt::convertAnimationValue(getAttributeEnumByAPIName(o3tl::getToken(aNameList, 0, ';')), rAny);
+ }
+
+ css::uno::Any convertPointPercent(const css::awt::Point& rPoint)
+ {
+ css::animations::ValuePair aPair;
+ // rPoint.X and rPoint.Y are in 1000th of a percent, but we only need ratio.
+ aPair.First <<= static_cast<double>(rPoint.X) / 100000.0;
+ aPair.Second <<= static_cast<double>(rPoint.Y) / 100000.0;
+ return Any(aPair);
+ }
+}
+
+namespace oox::ppt {
+
+ namespace {
+
+ struct AnimColor
+ {
+ AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
+ : colorSpace( cs ), one( o ), two( t ), three( th )
+ {
+ }
+
+ Any get() const
+ {
+ sal_Int32 nColor;
+ Any aColor;
+
+ switch( colorSpace )
+ {
+ case AnimationColorSpace::HSL:
+ aColor <<= Sequence< double >{ one / 100000.0, two / 100000.0, three / 100000.0 };
+ break;
+ case AnimationColorSpace::RGB:
+ nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
+ | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
+ | ( ( ( three * 128 ) / 1000 ) & 0xff );
+ aColor <<= nColor;
+ break;
+ default:
+ nColor = 0;
+ aColor <<= nColor;
+ break;
+ }
+ return aColor;
+ }
+
+ sal_Int16 colorSpace;
+ sal_Int32 one;
+ sal_Int32 two;
+ sal_Int32 three;
+ };
+
+ /** CT_TLMediaNodeAudio
+ CT_TLMediaNodeVideo */
+ class MediaNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ MediaNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, pNode )
+ , mbIsNarration( false )
+ , mbFullScrn( false )
+ , mbHideDuringShow(false)
+ {
+ AttributeList attribs( xAttribs );
+
+ switch( aElement )
+ {
+ case PPT_TOKEN( audio ):
+ mbIsNarration = attribs.getBool( XML_isNarration, false );
+ break;
+ case PPT_TOKEN( video ):
+ mbFullScrn = attribs.getBool( XML_fullScrn, false );
+ break;
+ default:
+ break;
+ }
+ }
+
+ virtual void onEndElement() override
+ {
+ sal_Int32 aElement = getCurrentElement();
+ if( aElement == PPT_TOKEN( audio ) )
+ {
+ mpNode->getNodeProperties()[NP_ISNARRATION] <<= mbIsNarration;
+ }
+ else if( aElement == PPT_TOKEN( video ) )
+ {
+ // TODO deal with mbFullScrn
+ }
+ else if (aElement == PPT_TOKEN(cMediaNode))
+ {
+ mpNode->getNodeProperties()[NP_HIDEDURINGSHOW] <<= mbHideDuringShow;
+ }
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cTn ):
+ return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
+ case PPT_TOKEN( tgtEl ):
+ return new TimeTargetElementContext( *this, mpNode->getTarget() );
+ case PPT_TOKEN(cMediaNode):
+ mbHideDuringShow = !rAttribs.getBool(XML_showWhenStopped, true);
+ break;
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+ private:
+ bool mbIsNarration;
+ bool mbFullScrn;
+ bool mbHideDuringShow;
+ };
+
+ /** CT_TLSetBehavior
+ */
+ class SetTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ SetTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, pNode )
+ {
+
+ }
+
+ virtual ~SetTimeNodeContext() noexcept override
+ {
+ if(maTo.hasValue())
+ {
+ convertAnimationValueWithTimeNode(mpNode, maTo);
+ mpNode->setTo(maTo);
+ }
+
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ case PPT_TOKEN( to ):
+ // CT_TLAnimVariant
+ return new AnimVariantContext( *this, aElementToken, maTo );
+ default:
+ break;
+ }
+
+ return this;
+ }
+ private:
+ Any maTo;
+ };
+
+ /** CT_TLCommandBehavior
+ */
+ class CmdTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ CmdTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, pNode )
+ , maType(0)
+ {
+ switch ( aElement )
+ {
+ case PPT_TOKEN( cmd ):
+ msCommand = xAttribs->getOptionalValue( XML_cmd );
+ maType = xAttribs->getOptionalValueToken( XML_type, 0 );
+ break;
+ default:
+ break;
+ }
+ }
+
+ virtual void onEndElement() override
+ {
+ if( !isCurrentElement( PPT_TOKEN( cmd ) ) )
+ return;
+
+ try {
+ // see sd/source/filter/ppt/pptinanimations.cxx
+ // in AnimationImporter::importCommandContainer()
+ // REFACTOR?
+ // a good chunk of this code has been copied verbatim *sigh*
+ sal_Int16 nCommand = EffectCommands::CUSTOM;
+ NamedValue aParamValue;
+
+ switch( maType )
+ {
+ case XML_verb:
+ aParamValue.Name = "Verb";
+ // TODO make sure msCommand has what we want
+ aParamValue.Value <<= msCommand.toInt32();
+ nCommand = EffectCommands::VERB;
+ break;
+ case XML_evt:
+ case XML_call:
+ if ( msCommand == "onstopaudio" )
+ {
+ nCommand = EffectCommands::STOPAUDIO;
+ }
+ else if ( msCommand == "play" )
+ {
+ nCommand = EffectCommands::PLAY;
+ }
+ else if (msCommand.startsWith("playFrom"))
+ {
+ std::u16string_view aMediaTime( msCommand.subView( 9, msCommand.getLength() - 10 ) );
+ rtl_math_ConversionStatus eStatus;
+ double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, u'.', u',', &eStatus );
+ if( eStatus == rtl_math_ConversionStatus_Ok )
+ {
+ aParamValue.Name = "MediaTime";
+ aParamValue.Value <<= fMediaTime;
+ }
+ nCommand = EffectCommands::PLAY;
+ }
+ else if ( msCommand == "togglePause" )
+ {
+ nCommand = EffectCommands::TOGGLEPAUSE;
+ }
+ else if ( msCommand == "stop" )
+ {
+ nCommand = EffectCommands::STOP;
+ }
+ break;
+ }
+ mpNode->getNodeProperties()[ NP_COMMAND ] <<= nCommand;
+ if( nCommand == EffectCommands::CUSTOM )
+ {
+ SAL_WARN("oox.ppt", "OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
+ aParamValue.Name = "UserDefined";
+ aParamValue.Value <<= msCommand;
+ }
+ if( aParamValue.Value.hasValue() )
+ {
+ Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
+ mpNode->getNodeProperties()[ NP_PARAMETER ] <<= aParamSeq;
+ }
+ }
+ catch( RuntimeException& )
+ {
+ TOOLS_WARN_EXCEPTION("oox.ppt", "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
+ }
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+ private:
+ OUString msCommand;
+ sal_Int32 maType;
+ };
+
+ /** CT_TLTimeNodeSequence
+ */
+ class SequenceTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ SequenceTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, pNode )
+ , mnNextAc(0)
+ , mnPrevAc(0)
+ {
+ AttributeList attribs(xAttribs);
+ mbConcurrent = attribs.getBool( XML_concurrent, false );
+ mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
+ mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cTn ):
+ return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
+ case PPT_TOKEN( nextCondLst ):
+ return new CondListContext( *this, aElementToken, mpNode, mpNode->getNextCondition() );
+ case PPT_TOKEN( prevCondLst ):
+ return new CondListContext( *this, aElementToken, mpNode, mpNode->getPrevCondition() );
+ default:
+ break;
+ }
+
+ return this;
+ }
+ private:
+ bool mbConcurrent;
+ sal_Int32 mnNextAc, mnPrevAc;
+ };
+
+ /** CT_TLTimeNodeParallel
+ * CT_TLTimeNodeExclusive
+ */
+ class ParallelExclTimeNodeContext
+ : public TimeNodeContext
+ {
+ public:
+ ParallelExclTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const TimeNodePtr & pNode )
+ : TimeNodeContext( rParent, aElement, pNode )
+ {
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cTn ):
+ return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+ protected:
+
+ };
+
+ /** CT_TLAnimateColorBehavior */
+ class AnimColorContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimColorContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) noexcept
+ : TimeNodeContext( rParent, aElement, pNode )
+ , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
+ , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
+ , mbHasByColor( false )
+ , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
+ {
+ }
+
+ virtual void onEndElement() override
+ {
+ //xParentNode
+ if( !isCurrentElement( mnElement ) )
+ return;
+
+ NodePropertyMap & rProps(mpNode->getNodeProperties());
+ rProps[ NP_DIRECTION ] <<= mnDir == XML_cw;
+ rProps[ NP_COLORINTERPOLATION ] <<= mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB;
+ const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
+ if( maToClr.isUsed() )
+ mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
+ if( maFromClr.isUsed() )
+ mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
+ if( mbHasByColor )
+ mpNode->setBy( m_byColor.get() );
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( hsl ):
+ // CT_TLByHslColorTransform
+ {
+ if( mbHasByColor )
+ {
+ m_byColor.colorSpace = AnimationColorSpace::HSL;
+ m_byColor.one = rAttribs.getInteger( XML_h, 0 );
+ m_byColor.two = rAttribs.getInteger( XML_s, 0 );
+ m_byColor.three = rAttribs.getInteger( XML_l, 0 );
+ }
+ return this;
+ }
+ case PPT_TOKEN( rgb ):
+ {
+ if( mbHasByColor )
+ {
+ // CT_TLByRgbColorTransform
+ m_byColor.colorSpace = AnimationColorSpace::RGB;
+ m_byColor.one = rAttribs.getInteger( XML_r, 0 );
+ m_byColor.two = rAttribs.getInteger( XML_g, 0 );
+ m_byColor.three = rAttribs.getInteger( XML_b, 0 );
+ }
+ return this;
+ }
+ case PPT_TOKEN( by ):
+ // CT_TLByAnimateColorTransform
+ mbHasByColor = true;
+ return this;
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ case PPT_TOKEN( to ):
+ // CT_Color
+ return new ColorContext( *this, maToClr );
+ case PPT_TOKEN( from ):
+ // CT_Color
+ return new ColorContext( *this, maFromClr );
+
+ default:
+ break;
+ }
+
+ return this;
+ }
+
+ private:
+ sal_Int32 mnColorSpace;
+ sal_Int32 mnDir;
+ bool mbHasByColor;
+ AnimColor m_byColor;
+ oox::drawingml::Color maToClr;
+ oox::drawingml::Color maFromClr;
+ };
+
+ /** CT_TLAnimateBehavior */
+ class AnimContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) noexcept
+ : TimeNodeContext( rParent, aElement, pNode )
+ {
+ NodePropertyMap & aProps( pNode->getNodeProperties() );
+ sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
+ if(nCalcMode)
+ {
+ sal_Int16 nEnum = 0;
+ switch(nCalcMode)
+ {
+ case XML_discrete:
+ nEnum = AnimationCalcMode::DISCRETE;
+ break;
+ case XML_lin:
+ nEnum = AnimationCalcMode::LINEAR;
+ break;
+ case XML_fmla:
+ default:
+ // TODO what value is good ?
+ nEnum = AnimationCalcMode::DISCRETE;
+ break;
+ }
+ aProps[ NP_CALCMODE ] <<= nEnum;
+ }
+
+ msFrom = xAttribs->getOptionalValue(XML_from);
+ msTo = xAttribs->getOptionalValue(XML_to);
+ msBy = xAttribs->getOptionalValue(XML_by);
+
+ mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
+ }
+
+ virtual ~AnimContext() noexcept override
+ {
+ if (!msFrom.isEmpty())
+ {
+ css::uno::Any aAny;
+ aAny <<= msFrom;
+ convertAnimationValueWithTimeNode(mpNode, aAny);
+ mpNode->setFrom(aAny);
+ }
+
+ if (!msTo.isEmpty())
+ {
+ css::uno::Any aAny;
+ aAny <<= msTo;
+ convertAnimationValueWithTimeNode(mpNode, aAny);
+ mpNode->setTo(aAny);
+ }
+
+ if (!msBy.isEmpty())
+ {
+ css::uno::Any aAny;
+ aAny <<= msBy;
+ convertAnimationValueWithTimeNode(mpNode, aAny);
+ mpNode->setBy(aAny);
+ }
+
+ int nKeyTimes = maTavList.size();
+ if( nKeyTimes <= 0)
+ return;
+
+ int i=0;
+ Sequence< double > aKeyTimes( nKeyTimes );
+ auto pKeyTimes = aKeyTimes.getArray();
+ Sequence< Any > aValues( nKeyTimes );
+ auto pValues = aValues.getArray();
+
+ NodePropertyMap & aProps( mpNode->getNodeProperties() );
+ for (auto const& tav : maTavList)
+ {
+ // TODO what to do if it is Timing_INFINITE ?
+ Any aTime = GetTimeAnimateValueTime( tav.msTime );
+ aTime >>= pKeyTimes[i];
+ pValues[i] = tav.maValue;
+ convertAnimationValueWithTimeNode(mpNode, pValues[i]);
+
+ // Examine pptx documents and find that only the first tav
+ // has the formula set. The formula can be used for the whole.
+ if (!tav.msFormula.isEmpty())
+ {
+ OUString sFormula = tav.msFormula;
+ (void)convertMeasure(sFormula);
+ aProps[NP_FORMULA] <<= sFormula;
+ }
+
+ ++i;
+ }
+ aProps[ NP_VALUES ] <<= aValues;
+ aProps[ NP_KEYTIMES ] <<= aKeyTimes;
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ case PPT_TOKEN( tavLst ):
+ return new TimeAnimValueListContext ( *this, maTavList );
+ default:
+ break;
+ }
+
+ return this;
+ }
+ private:
+ sal_Int32 mnValueType;
+ TimeAnimationValueList maTavList;
+ OUString msFrom;
+ OUString msTo;
+ OUString msBy;
+ };
+
+ /** CT_TLAnimateScaleBehavior */
+ class AnimScaleContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimScaleContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) noexcept
+ : TimeNodeContext( rParent, aElement, pNode )
+ , mbZoomContents( false )
+ {
+ AttributeList attribs( xAttribs );
+ // TODO what to do with mbZoomContents
+ mbZoomContents = attribs.getBool( XML_zoomContents, false );
+ pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
+ <<= sal_Int16(AnimationTransformType::SCALE);
+ }
+
+ virtual void onEndElement() override
+ {
+ if( !isCurrentElement( mnElement ) )
+ return;
+
+ if( maTo.hasValue() )
+ {
+ mpNode->setTo( maTo );
+ }
+ if( maBy.hasValue() )
+ {
+ mpNode->setBy( maBy );
+ }
+ if( maFrom.hasValue() )
+ {
+ mpNode->setFrom( maFrom );
+ }
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ case PPT_TOKEN( to ):
+ {
+ // CT_TLPoint
+ maTo = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
+ return this;
+ }
+ case PPT_TOKEN( from ):
+ {
+ // CT_TLPoint
+ maFrom = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
+ return this;
+ }
+ case PPT_TOKEN( by ):
+ {
+ // CT_TLPoint
+ css::awt::Point aPoint = GetPointPercent(rAttribs.getFastAttributeList());
+ // We got ending values instead of offset values, so subtract 100% from them.
+ aPoint.X -= 100000;
+ aPoint.Y -= 100000;
+ maBy = convertPointPercent(aPoint);
+ return this;
+ }
+ default:
+ break;
+ }
+
+ return this;
+ }
+ private:
+ Any maBy;
+ Any maFrom;
+ Any maTo;
+ bool mbZoomContents;
+ };
+
+ /** CT_TLAnimateRotationBehavior */
+ class AnimRotContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimRotContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) noexcept
+ : TimeNodeContext( rParent, aElement, pNode )
+ {
+ AttributeList attribs( xAttribs );
+
+ pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
+ <<= sal_Int16(AnimationTransformType::ROTATE);
+ // see also DFF_msofbtAnimateRotationData in
+ // sd/source/filter/ppt/pptinanimations.cxx
+ if(attribs.hasAttribute( XML_by ) )
+ {
+ double fBy = attribs.getDouble( XML_by, 0.0 ) / PER_DEGREE; //1 PowerPoint-angle-unit = 1/60000 degree
+ pNode->setBy( Any( fBy ) );
+ }
+ if(attribs.hasAttribute( XML_from ) )
+ {
+ double fFrom = attribs.getDouble( XML_from, 0.0 ) / PER_DEGREE;
+ pNode->setFrom( Any( fFrom ) );
+ }
+ if(attribs.hasAttribute( XML_to ) )
+ {
+ double fTo = attribs.getDouble( XML_to, 0.0 ) / PER_DEGREE;
+ pNode->setTo( Any( fTo ) );
+ }
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ default:
+ break;
+ }
+
+ return this;
+ }
+ };
+
+ /** CT_TLAnimateMotionBehavior */
+ class AnimMotionContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimMotionContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) noexcept
+ : TimeNodeContext( rParent, aElement, pNode )
+ {
+ pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
+ <<= sal_Int16(AnimationTransformType::TRANSLATE);
+
+ AttributeList attribs( xAttribs );
+ sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
+ if( nOrigin != 0 )
+ {
+ switch(nOrigin)
+ {
+ case XML_layout:
+ case XML_parent:
+ break;
+ }
+ // TODO
+ }
+
+ OUString aStr = xAttribs->getOptionalValue( XML_path );
+ // E can appear inside a number, so we only check for its presence at the end
+ aStr = aStr.trim();
+ if (aStr.endsWith("E"))
+ aStr = aStr.copy(0, aStr.getLength() - 1);
+ aStr = aStr.trim();
+ pNode->getNodeProperties()[ NP_PATH ] <<= aStr;
+ mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
+ msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
+ mnAngle = attribs.getInteger( XML_rAng, 0 );
+ // TODO make sure the units are right. Likely not.
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ case PPT_TOKEN( to ):
+ {
+ // CT_TLPoint
+ awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setTo( rAny );
+ return this;
+ }
+ case PPT_TOKEN( from ):
+ {
+ // CT_TLPoint
+ awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setFrom( rAny );
+ return this;
+ }
+ case PPT_TOKEN( by ):
+ {
+ // CT_TLPoint
+ awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
+ Any rAny;
+ rAny <<= p.X;
+ rAny <<= p.Y;
+ mpNode->setBy( rAny );
+ return this;
+ }
+ case PPT_TOKEN( rCtr ):
+ {
+ // CT_TLPoint
+ awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
+ // TODO push
+ (void)p;
+ return this;
+ }
+ default:
+ break;
+ }
+
+ return this;
+ }
+ private:
+ OUString msPtsTypes;
+ sal_Int32 mnPathEditMode;
+ sal_Int32 mnAngle;
+ };
+
+ /** CT_TLAnimateEffectBehavior */
+ class AnimEffectContext
+ : public TimeNodeContext
+ {
+ public:
+ AnimEffectContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode ) noexcept
+ : TimeNodeContext( rParent, aElement, pNode )
+ {
+ sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
+ OUString sFilter = xAttribs->getOptionalValue( XML_filter );
+ // TODO
+// OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
+
+ if( !sFilter.isEmpty() )
+ {
+ SlideTransition aFilter( sFilter );
+ aFilter.setMode( nDir != XML_out );
+ pNode->setTransitionFilter( aFilter );
+ }
+ }
+
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
+ {
+ switch ( aElementToken )
+ {
+ case PPT_TOKEN( cBhvr ):
+ return new CommonBehaviorContext ( *this, mpNode );
+ case PPT_TOKEN( progress ):
+ return new AnimVariantContext( *this, aElementToken, maProgress );
+ // TODO handle it.
+ default:
+ break;
+ }
+
+ return this;
+ }
+ private:
+ Any maProgress;
+ };
+
+ }
+
+ rtl::Reference<TimeNodeContext> TimeNodeContext::makeContext(
+ FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const Reference< XFastAttributeList >& xAttribs,
+ const TimeNodePtr & pNode )
+ {
+ rtl::Reference<TimeNodeContext> pCtx;
+ switch( aElement )
+ {
+ case PPT_TOKEN( animClr ):
+ pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( par ):
+ pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
+ break;
+ case PPT_TOKEN( seq ):
+ pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( excl ):
+ pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
+ break;
+ case PPT_TOKEN( anim ):
+ pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animEffect ):
+ pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animMotion ):
+ pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animRot ):
+ pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( animScale ):
+ pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( cmd ):
+ pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ case PPT_TOKEN( set ):
+ pCtx = new SetTimeNodeContext( rParent, aElement, pNode );
+ break;
+ case PPT_TOKEN( audio ):
+ case PPT_TOKEN( video ):
+ pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
+ break;
+ default:
+ break;
+ }
+ return pCtx;
+ }
+
+ TimeNodeContext::TimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
+ const TimeNodePtr & pNode ) noexcept
+ : FragmentHandler2( rParent )
+ , mnElement( aElement )
+ , mpNode( pNode )
+ {
+ }
+
+ TimeNodeContext::~TimeNodeContext( ) noexcept
+ {
+
+ }
+
+ TimeNodeListContext::TimeNodeListContext( FragmentHandler2 const & rParent, TimeNodePtrList & aList )
+ noexcept
+ : FragmentHandler2( rParent )
+ , maList( aList )
+ {
+ }
+
+ TimeNodeListContext::~TimeNodeListContext( ) noexcept
+ {
+ }
+
+ ::oox::core::ContextHandlerRef TimeNodeListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+ sal_Int16 nNodeType;
+
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( par ):
+ nNodeType = AnimationNodeType::PAR;
+ break;
+ case PPT_TOKEN( seq ):
+ nNodeType = AnimationNodeType::SEQ;
+ break;
+ case PPT_TOKEN( excl ):
+ // TODO pick the right type. We choose parallel for now as
+ // there does not seem to be an "Exclusive"
+ nNodeType = AnimationNodeType::PAR;
+ break;
+ case PPT_TOKEN( anim ):
+ nNodeType = AnimationNodeType::ANIMATE;
+ break;
+ case PPT_TOKEN( animClr ):
+ nNodeType = AnimationNodeType::ANIMATECOLOR;
+ break;
+ case PPT_TOKEN( animEffect ):
+ nNodeType = AnimationNodeType::TRANSITIONFILTER;
+ break;
+ case PPT_TOKEN( animMotion ):
+ nNodeType = AnimationNodeType::ANIMATEMOTION;
+ break;
+ case PPT_TOKEN( animRot ):
+ case PPT_TOKEN( animScale ):
+ nNodeType = AnimationNodeType::ANIMATETRANSFORM;
+ break;
+ case PPT_TOKEN( cmd ):
+ nNodeType = AnimationNodeType::COMMAND;
+ break;
+ case PPT_TOKEN( set ):
+ nNodeType = AnimationNodeType::SET;
+ break;
+ case PPT_TOKEN( audio ):
+ nNodeType = AnimationNodeType::AUDIO;
+ break;
+ case PPT_TOKEN( video ):
+ nNodeType = AnimationNodeType::AUDIO;
+ SAL_WARN("oox.ppt", "OOX: video requested, gave Audio instead" );
+ break;
+
+ default:
+ nNodeType = AnimationNodeType::CUSTOM;
+ SAL_INFO("oox.ppt", "unhandled token " << aElementToken);
+ break;
+ }
+
+ TimeNodePtr pNode = std::make_shared<TimeNode>(nNodeType);
+ maList.push_back( pNode );
+ rtl::Reference<FragmentHandler2> pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );
+
+ return pContext ? pContext : this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/timetargetelementcontext.cxx b/oox/source/ppt/timetargetelementcontext.cxx
new file mode 100644
index 000000000..bf74b3353
--- /dev/null
+++ b/oox/source/ppt/timetargetelementcontext.cxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include "timetargetelementcontext.hxx"
+
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+
+#include <oox/helper/attributelist.hxx>
+#include <drawingml/embeddedwavaudiofile.hxx>
+#include <oox/token/namespaces.hxx>
+#include <oox/token/tokens.hxx>
+#include <oox/core/xmlfilterbase.hxx>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <avmedia/mediaitem.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::xml::sax;
+using namespace ::oox::core;
+
+namespace oox::ppt {
+
+ namespace {
+
+ // CT_TLShapeTargetElement
+ class ShapeTargetElementContext
+ : public FragmentHandler2
+ {
+ public:
+ ShapeTargetElementContext( FragmentHandler2 const & rParent, ShapeTargetElement & aValue )
+ : FragmentHandler2( rParent )
+ , bTargetSet(false)
+ , maShapeTarget(aValue)
+ {
+ }
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
+ {
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( bg ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_bg;
+ return this;
+ case PPT_TOKEN( txEl ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_txEl;
+ return this;
+ case PPT_TOKEN( subSp ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_subSp;
+ maShapeTarget.msSubShapeId = rAttribs.getString( XML_spid, OUString() );
+ return this;
+ case PPT_TOKEN( graphicEl ):
+ return this; // needs a:dgm for the target
+ case A_TOKEN( dgm ):
+ bTargetSet = true;
+ maShapeTarget.mnType = XML_dgm;
+ maShapeTarget.msSubShapeId = rAttribs.getString( XML_id, OUString() );
+ return this;
+ case PPT_TOKEN( oleChartEl ):
+ bTargetSet = true;
+ // TODO
+ return this;
+ case PPT_TOKEN( charRg ):
+ case PPT_TOKEN( pRg ):
+ if( bTargetSet && maShapeTarget.mnType == XML_txEl )
+ {
+ maShapeTarget.mnRangeType = getBaseToken( aElementToken );
+ maShapeTarget.maRange = drawingml::GetIndexRange( rAttribs.getFastAttributeList() );
+ }
+ return this;
+ default:
+ break;
+ }
+ return this;
+ }
+
+ private:
+ bool bTargetSet;
+ ShapeTargetElement & maShapeTarget;
+ };
+
+ }
+
+ TimeTargetElementContext::TimeTargetElementContext( FragmentHandler2 const & rParent, const AnimTargetElementPtr & pValue )
+ : FragmentHandler2( rParent ),
+ mpTarget( pValue )
+ {
+ OSL_ENSURE( mpTarget, "no valid target passed" );
+ }
+
+ TimeTargetElementContext::~TimeTargetElementContext( ) noexcept
+ {
+ }
+
+ ::oox::core::ContextHandlerRef TimeTargetElementContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
+ {
+ switch( aElementToken )
+ {
+ case PPT_TOKEN( inkTgt ):
+ {
+ mpTarget->mnType = XML_inkTgt;
+ OUString aId = rAttribs.getString( XML_spid, OUString() );
+ if( !aId.isEmpty() )
+ {
+ mpTarget->msValue = aId;
+ }
+ return this;
+ }
+ case PPT_TOKEN( sldTgt ):
+ mpTarget->mnType = XML_sldTgt;
+ return this;
+ case PPT_TOKEN( sndTgt ):
+ {
+ mpTarget->mnType = XML_sndTgt;
+
+#if HAVE_FEATURE_AVMEDIA
+ OUString srcFile = drawingml::getEmbeddedWAVAudioFile(getRelations(), rAttribs);
+ Reference<css::io::XInputStream>
+ xInputStream = getFilter().openInputStream(srcFile);
+
+ if (xInputStream.is())
+ {
+ ::avmedia::EmbedMedia(getFilter().getModel(), srcFile, mpTarget->msValue, xInputStream);
+ xInputStream->closeInput();
+ }
+#endif
+ break;
+ }
+ case PPT_TOKEN( spTgt ):
+ {
+ mpTarget->mnType = XML_spTgt;
+ OUString aId = rAttribs.getString( XML_spid, OUString() );
+ mpTarget->msValue = aId;
+ return new ShapeTargetElementContext( *this, mpTarget->maShapeTarget );
+ }
+ default:
+ SAL_INFO(
+ "oox.ppt",
+ "unhandled tag " << getBaseToken(aElementToken)
+ << " in TL_TimeTargetElement");
+ break;
+ }
+
+ return this;
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/ppt/timetargetelementcontext.hxx b/oox/source/ppt/timetargetelementcontext.hxx
new file mode 100644
index 000000000..29fed88b6
--- /dev/null
+++ b/oox/source/ppt/timetargetelementcontext.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_OOX_SOURCE_PPT_TIMETARGETELEMENTCONTEXT_HXX
+#define INCLUDED_OOX_SOURCE_PPT_TIMETARGETELEMENTCONTEXT_HXX
+
+#include <oox/core/fragmenthandler2.hxx>
+#include <oox/ppt/animationspersist.hxx>
+
+namespace oox::ppt {
+
+ /** context CT_TLTimeTargetElement */
+ class TimeTargetElementContext
+ : public ::oox::core::FragmentHandler2
+ {
+ public:
+ TimeTargetElementContext( ::oox::core::FragmentHandler2 const & rParent, const AnimTargetElementPtr & aValue );
+ virtual ~TimeTargetElementContext( ) noexcept override;
+ virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override;
+
+ private:
+ AnimTargetElementPtr mpTarget;
+ };
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */