LibreOffice Module oox (master) 1
slidepersist.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
21#include <com/sun/star/drawing/XDrawPage.hpp>
22#include <com/sun/star/drawing/XShapes.hpp>
23#include <com/sun/star/frame/XModel.hpp>
24#include <oox/ppt/timenode.hxx>
25#include <oox/ppt/pptshape.hxx>
32#include <oox/token/properties.hxx>
33#include <oox/token/tokens.hxx>
37
38#include <osl/diagnose.h>
39
40#include <com/sun/star/style/XStyle.hpp>
41#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
42#include <com/sun/star/container/XNamed.hpp>
43#include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
44#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
45#include <com/sun/star/container/XIdentifierContainer.hpp>
46#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
47#include <utility>
48
49using namespace ::com::sun::star;
50using namespace ::oox::core;
51using namespace ::com::sun::star::uno;
52using namespace ::com::sun::star::drawing;
53using namespace ::com::sun::star::container;
54using namespace ::com::sun::star::animations;
55
56
57namespace oox::ppt {
58
59SlidePersist::SlidePersist( XmlFilterBase& rFilter, bool bMaster, bool bNotes,
60 const css::uno::Reference< css::drawing::XDrawPage >& rxPage,
61 oox::drawingml::ShapePtr pShapesPtr, drawingml::TextListStylePtr pDefaultTextStyle )
62: mpDrawingPtr( std::make_shared<oox::vml::Drawing>( rFilter, rxPage, oox::vml::VMLDRAWING_POWERPOINT ) )
63, mxPage( rxPage )
64, maShapesPtr(std::move( pShapesPtr ))
65, mnLayoutValueToken( 0 )
66, mbMaster( bMaster )
67, mbNotes ( bNotes )
68, maDefaultTextStylePtr(std::move( pDefaultTextStyle ))
69, maTitleTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
70, maBodyTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
71, maNotesTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
72, maOtherTextStylePtr( std::make_shared<oox::drawingml::TextListStyle>() )
73{
74#if OSL_DEBUG_LEVEL > 0
76#endif
77}
78
79#if OSL_DEBUG_LEVEL > 0
80css::uno::WeakReference< css::drawing::XDrawPage > SlidePersist::mxDebugPage;
81#endif
82
84{
85}
86
88{
89 sal_Int16 nLayout = 20; // 20 == blank (so many magic numbers :-( the description at com.sun.star.presentation.DrawPage.Layout does not help)
90 switch( mnLayoutValueToken )
91 {
92 case XML_blank: nLayout = 20; break;
93 case XML_chart: nLayout = 2; break;
94 case XML_chartAndTx: nLayout = 7; break;
95 case XML_clipArtAndTx: nLayout = 9; break;
96 case XML_clipArtAndVertTx: nLayout = 24; break;
97 case XML_fourObj: nLayout = 18; break;
98 case XML_obj: nLayout = 11; break;
99 case XML_objAndTx: nLayout = 13; break;
100 case XML_objOverTx: nLayout = 14; break;
101 case XML_tbl: nLayout = 8; break;
102 case XML_title: nLayout = 0; break;
103 case XML_titleOnly: nLayout = 19; break;
104 case XML_twoObj:
105 case XML_twoColTx: nLayout = 3; break;
106 case XML_twoObjAndTx: nLayout = 15; break;
107 case XML_twoObjOverTx: nLayout = 16; break;
108 case XML_tx: nLayout = 1; break;
109 case XML_txAndChart: nLayout = 4; break;
110 case XML_txAndClipArt: nLayout = 6; break;
111 case XML_txAndMedia: nLayout = 6; break;
112 case XML_txAndObj: nLayout = 10; break;
113 case XML_txAndTwoObj: nLayout = 12; break;
114 case XML_txOverObj: nLayout = 17; break;
115 case XML_vertTitleAndTx: nLayout = 22; break;
116 case XML_vertTitleAndTxOverChart: nLayout = 21; break;
117 case XML_vertTx: nLayout = 23; break;
118
119 case XML_twoTxTwoObj:
120 case XML_twoObjAndObj:
121 case XML_objTx:
122 case XML_picTx:
123 case XML_secHead:
124 case XML_objOnly:
125 case XML_objAndTwoObj:
126 case XML_mediaAndTx:
127 case XML_dgm:
128 case XML_cust:
129 default:
130 nLayout = 20;
131 }
132 return nLayout;
133}
134
135void SlidePersist::createXShapes( XmlFilterBase& rFilterBase )
136{
137 applyTextStyles( rFilterBase );
138
139 Reference< XShapes > xShapes( getPage() );
140 std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
141
142 for (auto const& shape : rShapes)
143 {
144 std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() );
145 for (auto const& child : rChildren)
146 {
147 PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
148 basegfx::B2DHomMatrix aTransformation;
149 if ( pPPTShape )
150 {
151 pPPTShape->addShape( rFilterBase, *this, getTheme().get(), xShapes, aTransformation, &getShapeMap() );
152 if (pPPTShape->isConnectorShape())
153 maConnectorShapeId.push_back(pPPTShape->getId());
154 if (!pPPTShape->getChildren().empty())
155 {
156 for (size_t i = 0; i < pPPTShape->getChildren().size(); i++)
157 {
158 if (pPPTShape->getChildren()[i]->isConnectorShape())
159 maConnectorShapeId.push_back(pPPTShape->getChildren()[i]->getId());
160 }
161 }
162 if (pPPTShape->hasBookmark())
163 addURLShapeId(pPPTShape->getId());
164 }
165 else
166 child->addShape( rFilterBase, getTheme().get(), xShapes, aTransformation, maShapesPtr->getFillProperties(), &getShapeMap() );
167 }
168 }
169
170 if (!maConnectorShapeId.empty())
172
173 Reference< XAnimationNodeSupplier > xNodeSupplier( getPage(), UNO_QUERY);
174 if( !xNodeSupplier.is() )
175 return;
176
177 Reference< XAnimationNode > xNode( xNodeSupplier->getAnimationNode() );
178 if( xNode.is() && !maTimeNodeList.empty() )
179 {
180 SlidePersistPtr pSlidePtr( shared_from_this() );
181 TimeNodePtr pNode(maTimeNodeList.front());
182 OSL_ENSURE( pNode, "pNode" );
183
184 Reference<XAnimationNode> xDummy;
185 pNode->setNode(rFilterBase, xNode, pSlidePtr, xDummy);
186 }
187}
188
189void SlidePersist::createBackground( const XmlFilterBase& rFilterBase )
190{
192 {
193 ::Color nPhClr = maBackgroundColor.isUsed() ?
194 maBackgroundColor.getColor( rFilterBase.getGraphicHelper() ) : API_RGB_TRANSPARENT;
195
197 aPropertyIds[oox::drawingml::ShapeProperty::FillGradient] = PROP_FillGradientName;
198 oox::drawingml::ShapePropertyInfo aPropInfo( aPropertyIds, true, false, true, false, false );
199 oox::drawingml::ShapePropertyMap aPropMap( rFilterBase.getModelObjectHelper(), aPropInfo );
200 mpBackgroundPropertiesPtr->pushToPropMap( aPropMap, rFilterBase.getGraphicHelper(), 0, nPhClr );
201 PropertySet( mxPage ).setProperty( PROP_Background, aPropMap.makePropertySet() );
202 }
203}
204
205static void setTextStyle( Reference< beans::XPropertySet > const & rxPropSet, const XmlFilterBase& rFilter,
206 oox::drawingml::TextListStylePtr const & pTextListStylePtr, int nLevel )
207{
208 ::oox::drawingml::TextParagraphProperties* pTextParagraphPropertiesPtr( &pTextListStylePtr->getListStyle()[ nLevel ] );
209 if( pTextParagraphPropertiesPtr == nullptr )
210 {
211 // no properties. return
212 return;
213 }
214
215 PropertyMap& rTextParagraphPropertyMap( pTextParagraphPropertiesPtr->getTextParagraphPropertyMap() );
216
217 PropertySet aPropSet( rxPropSet );
218 aPropSet.setProperties( rTextParagraphPropertyMap );
219 pTextParagraphPropertiesPtr->getTextCharacterProperties().pushToPropSet( aPropSet, rFilter );
220}
221
222void SlidePersist::applyTextStyles( const XmlFilterBase& rFilterBase )
223{
224 if ( !mbMaster )
225 return;
226
227 try
228 {
229 Reference< style::XStyleFamiliesSupplier > aXStyleFamiliesSupplier( rFilterBase.getModel(), UNO_QUERY_THROW );
230 Reference< container::XNameAccess > aXNameAccess( aXStyleFamiliesSupplier->getStyleFamilies() );
231 Reference< container::XNamed > aXNamed( mxPage, UNO_QUERY_THROW );
232
233 if ( aXNameAccess.is() )
234 {
235 oox::drawingml::TextListStylePtr pTextListStylePtr;
236 OUString aStyle;
237 OUString aFamily;
238
239 static const OUStringLiteral sOutline( u"outline1" );
240 static const OUStringLiteral sTitle( u"title" );
241 static const OUStringLiteral sStandard( u"standard" );
242 static const OUStringLiteral sSubtitle( u"subtitle" );
243
244 for( int i = 0; i < 4; i++ ) // todo: aggregation of bodystyle (subtitle)
245 {
246 switch( i )
247 {
248 case 0 : // title style
249 {
250 pTextListStylePtr = maTitleTextStylePtr;
251 aStyle = sTitle;
252 aFamily= aXNamed->getName();
253 break;
254 }
255 case 1 : // body style
256 {
257 pTextListStylePtr = maBodyTextStylePtr;
258 aStyle = sOutline;
259 aFamily= aXNamed->getName();
260 break;
261 }
262 case 3 : // notes style
263 {
264 pTextListStylePtr = maNotesTextStylePtr;
265 aStyle = sTitle;
266 aFamily= aXNamed->getName();
267 break;
268 }
269 case 4 : // standard style
270 {
271 pTextListStylePtr = maOtherTextStylePtr;
272 aStyle = sStandard;
273 aFamily = "graphics";
274 break;
275 }
276 case 5 : // subtitle
277 {
278 pTextListStylePtr = maBodyTextStylePtr;
279 aStyle = sSubtitle;
280 aFamily = aXNamed->getName();
281 break;
282 }
283 }
284 Reference< container::XNameAccess > xFamilies;
285 if ( aXNameAccess->hasByName( aFamily ) )
286 {
287 if( aXNameAccess->getByName( aFamily ) >>= xFamilies )
288 {
289 if ( xFamilies->hasByName( aStyle ) )
290 {
291 Reference< style::XStyle > aXStyle;
292 if ( xFamilies->getByName( aStyle ) >>= aXStyle )
293 {
294 Reference< beans::XPropertySet > xPropSet( aXStyle, UNO_QUERY_THROW );
295 setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, 0 );
296 setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, 0 );
297 if ( i == 1 /* BodyStyle */ )
298 {
299 for ( int nLevel = 1; nLevel < 5; nLevel++ )
300 {
301 {
302 char pOutline[ 9 ] = "outline1";
303 pOutline[ 7 ] = static_cast< char >( '0' + nLevel );
304 OUString sOutlineStyle( OUString::createFromAscii( pOutline ) );
305 if ( xFamilies->hasByName( sOutlineStyle ) )
306 {
307 xFamilies->getByName( sOutlineStyle ) >>= aXStyle;
308 if( aXStyle.is() )
309 xPropSet.set( aXStyle, UNO_QUERY_THROW );
310 }
311 }
312 setTextStyle( xPropSet, rFilterBase, maDefaultTextStylePtr, nLevel );
313 setTextStyle( xPropSet, rFilterBase, pTextListStylePtr, nLevel );
314 }
315 }
316 }
317 }
318 }
319 }
320 }
321 }
322 }
323 catch( const Exception& )
324 {
325 }
326}
327
329{
330 std::vector< oox::drawingml::ShapePtr >& rShapes( maShapesPtr->getChildren() );
331 for (auto const& shape : rShapes)
332 {
333 std::vector< oox::drawingml::ShapePtr >& rChildren( shape->getChildren() );
334 for (auto const& child : rChildren)
335 {
336 PPTShape* pPPTShape = dynamic_cast< PPTShape* >( child.get() );
337 if (!pPPTShape)
338 continue;
339 pPPTShape->setHiddenMasterShape( true );
340 }
341 }
342}
343
344Reference<XAnimationNode> SlidePersist::getAnimationNode(const OUString& sId) const
345{
346 const auto& pIter = maAnimNodesMap.find(sId);
347 if (pIter != maAnimNodesMap.end())
348 return pIter->second;
349
350 Reference<XAnimationNode> aResult;
351 return aResult;
352}
353
354// create connection between two shape with a connector shape.
356{
357 sal_Int32 nConnectorShapeCount = maConnectorShapeId.size();
358 for (sal_Int32 i = 0; i < nConnectorShapeCount; i++)
359 {
360 const auto& pIt = maShapeMap.find(maConnectorShapeId[i]);
361 if (pIt == maShapeMap.end())
362 continue;
363 oox::drawingml::ConnectorShapePropertiesList aConnectorShapeProperties
364 = pIt->second->getConnectorShapeProperties();
365 uno::Reference<drawing::XShape> xConnector(pIt->second->getXShape(), uno::UNO_QUERY);
366 uno::Reference<beans::XPropertySet> xPropertySet(xConnector, uno::UNO_QUERY);
367
368 if (xConnector.is())
369 {
370 sal_Int32 nCount = aConnectorShapeProperties.size();
371 for (sal_Int32 j = 0; j < nCount; j++)
372 {
373 OUString aDestShapeId = aConnectorShapeProperties[j].maDestShapeId;
374 const auto& pShape = maShapeMap.find(aDestShapeId);
375 if (pShape == maShapeMap.end())
376 continue;
377 uno::Reference<drawing::XShape> xShape(pShape->second->getXShape(), uno::UNO_QUERY);
378 if (xShape.is())
379 {
380 uno::Reference<drawing::XGluePointsSupplier> xSupplier(xShape, uno::UNO_QUERY);
381 css::uno::Reference<css::container::XIdentifierContainer> xGluePoints(
382 xSupplier->getGluePoints(), uno::UNO_QUERY);
383
384 sal_Int32 nCountGluePoints = xGluePoints->getIdentifiers().getLength();
385 sal_Int32 nGlueId = aConnectorShapeProperties[j].mnDestGlueId;
386
387 // The first 4 glue points belong to the bounding box.
388 if (nCountGluePoints > 4)
389 nGlueId += 4;
390 else
391 {
392 // change id of the left and right glue points of the bounding box (1 <-> 3)
393 if (nGlueId == 1)
394 nGlueId = 3; // Right
395 else if (nGlueId == 3)
396 nGlueId = 1; // Left
397 }
398
399 bool bStart = aConnectorShapeProperties[j].mbStartShape;
400 if (bStart)
401 {
402 xPropertySet->setPropertyValue("StartShape", uno::Any(xShape));
403 xPropertySet->setPropertyValue("StartGluePointIndex", uno::Any(nGlueId));
404 }
405 else
406 {
407 xPropertySet->setPropertyValue("EndShape", uno::Any(xShape));
408 xPropertySet->setPropertyValue("EndGluePointIndex", uno::Any(nGlueId));
409 }
410 }
411 }
412 }
413 }
414 maConnectorShapeId.clear();
415}
416
417}
418
419/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
A helper that maps property identifiers to property values.
Definition: propertymap.hxx:52
css::uno::Reference< css::beans::XPropertySet > makePropertySet() const
Creates a property set supporting the XPropertySet interface and inserts all properties.
A wrapper for a UNO property set.
Definition: propertyset.hxx:58
void setProperties(const css::uno::Sequence< OUString > &rPropNames, const css::uno::Sequence< css::uno::Any > &rValues)
Puts the passed properties into the property set.
bool setProperty(sal_Int32 nPropId, const Type &rValue)
Puts the passed value into the property set.
bool isUsed() const
Returns true, if the color is initialized.
Definition: color.hxx:87
::Color getColor(const GraphicHelper &rGraphicHelper, ::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:531
std::vector< ShapePtr > & getChildren()
Definition: shape.hxx:167
const OUString & getId() const
Definition: shape.hxx:174
bool hasBookmark() const
Definition: shape.hxx:144
void setHiddenMasterShape(bool bHiddenMasterShape)
Definition: shape.hxx:177
bool isConnectorShape() const
Definition: shape.hxx:141
TextCharacterProperties & getTextCharacterProperties()
void addShape(oox::core::XmlFilterBase &rFilterBase, const SlidePersist &rPersist, const oox::drawingml::Theme *pTheme, const css::uno::Reference< css::drawing::XShapes > &rxShapes, basegfx::B2DHomMatrix &aTransformation, ::oox::drawingml::ShapeIdMap *pShapeMap)
Definition: pptshape.cxx:160
::oox::drawingml::ShapeIdMap & getShapeMap()
oox::drawingml::TextListStylePtr maOtherTextStylePtr
std::map< OUString, ::oox::drawingml::ShapePtr > maShapeMap
void createBackground(const oox::core::XmlFilterBase &rFilterBase)
oox::drawingml::TextListStylePtr maBodyTextStylePtr
oox::drawingml::TextListStylePtr maTitleTextStylePtr
const css::uno::Reference< css::drawing::XDrawPage > & getPage() const
oox::drawingml::ShapePtr maShapesPtr
void createXShapes(oox::core::XmlFilterBase &rFilterBase)
static css::uno::WeakReference< css::drawing::XDrawPage > mxDebugPage
std::vector< OUString > maConnectorShapeId
const oox::drawingml::ThemePtr & getTheme() const
css::uno::Reference< css::drawing::XDrawPage > mxPage
void addURLShapeId(const OUString &rShapeId)
oox::drawingml::TextListStylePtr maDefaultTextStylePtr
css::uno::Reference< css::animations::XAnimationNode > getAnimationNode(const OUString &sId) const
oox::drawingml::TextListStylePtr maNotesTextStylePtr
void applyTextStyles(const oox::core::XmlFilterBase &rFilterBase)
std::map< OUString, css::uno::Reference< css::animations::XAnimationNode > > maAnimNodesMap
SlidePersist(oox::core::XmlFilterBase &rFilter, bool bMaster, bool bNotes, const css::uno::Reference< css::drawing::XDrawPage > &, oox::drawingml::ShapePtr pShapesPtr, ::oox::drawingml::TextListStylePtr)
oox::drawingml::Color maBackgroundColor
::std::vector< std::shared_ptr< TimeNode > > maTimeNodeList
oox::drawingml::FillPropertiesPtr mpBackgroundPropertiesPtr
sal_Int16 getLayoutFromValueToken() const
int nCount
float u
@ Exception
std::shared_ptr< T > make_shared(Args &&... args)
@ FillGradient
Explicit fill gradient or name of a fill gradient stored in a global container.
std::shared_ptr< Shape > ShapePtr
std::vector< ConnectorShapeProperties > ConnectorShapePropertiesList
Definition: shape.hxx:79
std::shared_ptr< TextListStyle > TextListStylePtr
std::shared_ptr< TimeNode > TimeNodePtr
Definition: timenode.hxx:44
std::shared_ptr< SlidePersist > SlidePersistPtr
static void setTextStyle(Reference< beans::XPropertySet > const &rxPropSet, const XmlFilterBase &rFilter, oox::drawingml::TextListStylePtr const &pTextListStylePtr, int nLevel)
@ VMLDRAWING_POWERPOINT
PowerPoint: OLE objects are part of DrawingML.
Definition: vmldrawing.hxx:57
const ::Color API_RGB_TRANSPARENT(ColorTransparency, 0xffffffff)
Transparent color for API calls.
const ShapePropertyIds & mrPropertyIds
static ShapePropertyInfo DEFAULT
True = use named fill hatch instead of explicit fill hatch.
void pushToPropSet(PropertySet &rPropSet, const ::oox::core::XmlFilterBase &rFilter) const
Writes the properties to the passed property set.
OUString sId