1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/ppt/pptshape.hxx"
21 #include "oox/core/xmlfilterbase.hxx"
22 #include "oox/drawingml/textbody.hxx"
24 #include <com/sun/star/container/XNamed.hpp>
25 #include <com/sun/star/beans/XMultiPropertySet.hpp>
26 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
27 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
28 #include <com/sun/star/text/XText.hpp>
29 #include <basegfx/matrix/b2dhommatrix.hxx>
30 #include "oox/ppt/slidepersist.hxx"
32 using namespace ::oox::core
;
33 using namespace ::oox::drawingml
;
34 using namespace ::com::sun::star
;
35 using namespace ::com::sun::star::awt
;
36 using namespace ::com::sun::star::uno
;
37 using namespace ::com::sun::star::beans
;
38 using namespace ::com::sun::star::frame
;
39 using namespace ::com::sun::star::text
;
40 using namespace ::com::sun::star::drawing
;
42 namespace oox
{ namespace ppt
{
44 PPTShape::PPTShape( const oox::ppt::ShapeLocation eShapeLocation
, const sal_Char
* pServiceName
)
45 : Shape( pServiceName
)
46 , meShapeLocation( eShapeLocation
)
47 , mbReferenced( sal_False
)
55 static const char* lclDebugSubType( sal_Int32 nType
)
80 return "unknown - please extend lclDebugSubType";
83 oox::drawingml::TextListStylePtr
PPTShape::getSubTypeTextListStyle( const SlidePersist
& rSlidePersist
, sal_Int32 nSubType
)
85 oox::drawingml::TextListStylePtr pTextListStyle
;
87 SAL_INFO("oox.ppt", "subtype style: " << lclDebugSubType( nSubType
) );
94 pTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getTitleTextStyle() : rSlidePersist
.getTitleTextStyle();
97 pTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getBodyTextStyle() : rSlidePersist
.getBodyTextStyle();
100 if ( rSlidePersist
.isNotesPage() )
101 pTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getNotesTextStyle() : rSlidePersist
.getNotesTextStyle();
103 pTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getBodyTextStyle() : rSlidePersist
.getBodyTextStyle();
107 return pTextListStyle
;
110 void PPTShape::addShape(
111 oox::core::XmlFilterBase
& rFilterBase
,
112 SlidePersist
& rSlidePersist
,
113 const oox::drawingml::Theme
* pTheme
,
114 const Reference
< XShapes
>& rxShapes
,
115 basegfx::B2DHomMatrix
& aTransformation
,
116 const awt::Rectangle
* pShapeRect
,
117 ::oox::drawingml::ShapeIdMap
* pShapeMap
)
119 SAL_INFO("oox.ppt","add shape id: " << msId
<< " location: " << ((meShapeLocation
== Master
) ? "master" : ((meShapeLocation
== Slide
) ? "slide" : ((meShapeLocation
== Layout
) ? "layout" : "other"))) << " subtype: " << mnSubType
<< " service: " << msServiceName
);
120 // only placeholder from layout are being inserted
121 if ( mnSubType
&& ( meShapeLocation
== Master
) )
125 OUString
sServiceName( msServiceName
);
126 if( !sServiceName
.isEmpty() )
128 oox::drawingml::TextListStylePtr aMasterTextListStyle
;
129 Reference
< lang::XMultiServiceFactory
> xServiceFact( rFilterBase
.getModel(), UNO_QUERY_THROW
);
130 sal_Bool bClearText
= sal_False
;
132 if ( sServiceName
!= "com.sun.star.drawing.GraphicObjectShape" &&
133 sServiceName
!= "com.sun.star.drawing.OLE2Shape" )
135 const OUString
sOutlinerShapeService( "com.sun.star.presentation.OutlinerShape" );
136 SAL_INFO("oox.ppt","has master: " << std::hex
<< rSlidePersist
.getMasterPersist().get());
142 sServiceName
= "com.sun.star.presentation.TitleTextShape";
143 aMasterTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getTitleTextStyle() : rSlidePersist
.getTitleTextStyle();
148 if ( ( meShapeLocation
== Master
) || ( meShapeLocation
== Layout
) )
149 sServiceName
= OUString();
151 sServiceName
= "com.sun.star.presentation.SubtitleShape";
152 aMasterTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getTitleTextStyle() : rSlidePersist
.getTitleTextStyle();
158 sServiceName
= sOutlinerShapeService
;
159 aMasterTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getBodyTextStyle() : rSlidePersist
.getBodyTextStyle();
164 if ( rSlidePersist
.isNotesPage() )
166 sServiceName
= "com.sun.star.presentation.NotesShape";
167 aMasterTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getNotesTextStyle() : rSlidePersist
.getNotesTextStyle();
171 sServiceName
= sOutlinerShapeService
;
172 aMasterTextListStyle
= rSlidePersist
.getMasterPersist().get() ? rSlidePersist
.getMasterPersist()->getBodyTextStyle() : rSlidePersist
.getBodyTextStyle();
177 sServiceName
= "com.sun.star.presentation.DateTimeShape";
178 bClearText
= sal_True
;
181 sServiceName
= "com.sun.star.presentation.HeaderShape";
182 bClearText
= sal_True
;
185 sServiceName
= "com.sun.star.presentation.FooterShape";
186 bClearText
= sal_True
;
189 sServiceName
= "com.sun.star.presentation.SlideNumberShape";
190 bClearText
= sal_True
;
193 sServiceName
= "com.sun.star.presentation.PageShape";
196 if ( meShapeLocation
== Layout
)
197 sServiceName
= sOutlinerShapeService
;
199 sServiceName
= "com.sun.star.presentation.ChartShape";
202 if ( meShapeLocation
== Layout
)
203 sServiceName
= sOutlinerShapeService
;
205 sServiceName
= "com.sun.star.presentation.TableShape";
208 if ( meShapeLocation
== Layout
)
209 sServiceName
= sOutlinerShapeService
;
211 sServiceName
= "com.sun.star.presentation.GraphicObjectShape";
214 if ( meShapeLocation
== Layout
)
215 sServiceName
= sOutlinerShapeService
;
217 sServiceName
= "com.sun.star.presentation.MediaShape";
220 if ( mnSubType
&& meShapeLocation
== Layout
)
221 sServiceName
= sOutlinerShapeService
;
226 SAL_INFO("oox.ppt","shape service: " << sServiceName
);
228 if( mnSubType
&& getSubTypeIndex().has() && meShapeLocation
== Layout
) {
229 oox::drawingml::ShapePtr pPlaceholder
= PPTShape::findPlaceholderByIndex( getSubTypeIndex().get(), rSlidePersist
.getShapes()->getChildren(), true );
230 if (!pPlaceholder
.get())
231 pPlaceholder
= PPTShape::findPlaceholder( mnSubType
, rSlidePersist
.getShapes()->getChildren(), true );
233 if (pPlaceholder
.get()) {
234 if( maSize
.Width
== 0 || maSize
.Height
== 0 ) {
235 awt::Size aSize
= maSize
;
236 if( maSize
.Width
== 0 )
237 aSize
.Width
= pPlaceholder
->getSize().Width
;
238 if( maSize
.Height
== 0 )
239 aSize
.Height
= pPlaceholder
->getSize().Height
;
241 if ( maPosition
.X
== 0 || maPosition
.Y
== 0 ) {
242 awt::Point aPosition
= maPosition
;
243 if( maPosition
.X
== 0 )
244 aPosition
.X
= pPlaceholder
->getPosition().X
;
245 if( maPosition
.Y
== 0 )
246 aPosition
.Y
= pPlaceholder
->getPosition().Y
;
247 setPosition( aPosition
);
253 // use placeholder index if possible
254 if( mnSubType
&& getSubTypeIndex().has() && rSlidePersist
.getMasterPersist().get() ) {
255 oox::drawingml::ShapePtr pPlaceholder
= PPTShape::findPlaceholderByIndex( getSubTypeIndex().get(), rSlidePersist
.getMasterPersist()->getShapes()->getChildren() );
256 // TODO: Check if this is required for non-notes slides as well...
257 if( rSlidePersist
.isNotesPage() && pPlaceholder
.get() && pPlaceholder
->getSubType() != getSubType() )
258 pPlaceholder
.reset();
260 if( pPlaceholder
.get()) {
261 SAL_INFO("oox.ppt","found placeholder with index: " << getSubTypeIndex().get() << " and type: " << lclDebugSubType( mnSubType
));
263 if( pPlaceholder
.get() ) {
264 PPTShape
* pPPTPlaceholder
= dynamic_cast< PPTShape
* >( pPlaceholder
.get() );
265 TextListStylePtr
pNewTextListStyle ( new TextListStyle() );
267 if( pPlaceholder
->getTextBody() ) {
269 pNewTextListStyle
->apply( pPlaceholder
->getTextBody()->getTextListStyle() );
270 if( pPlaceholder
->getMasterTextListStyle().get() )
271 pNewTextListStyle
->apply( *pPlaceholder
->getMasterTextListStyle() );
273 // SAL_INFO("oox.ppt","placeholder body style");
274 // pPlaceholder->getTextBody()->getTextListStyle().dump();
275 // SAL_INFO("oox.ppt","master text list style");
276 // pPlaceholder->getMasterTextListStyle()->dump();
278 aMasterTextListStyle
= pNewTextListStyle
;
279 // SAL_INFO("oox.ppt","combined master text list style");
280 // aMasterTextListStyle->dump();
282 if( pPPTPlaceholder
->mpPlaceholder
.get() ) {
283 SAL_INFO("oox.ppt","placeholder has parent placeholder: " << pPPTPlaceholder
->mpPlaceholder
->getId() << " type: " << lclDebugSubType( pPPTPlaceholder
->mpPlaceholder
->getSubType() ) << " index: " << pPPTPlaceholder
->mpPlaceholder
->getSubTypeIndex().get() );
284 SAL_INFO("oox.ppt","has textbody " << (pPPTPlaceholder
->mpPlaceholder
->getTextBody() != 0) );
285 TextListStylePtr pPlaceholderStyle
= getSubTypeTextListStyle( rSlidePersist
, pPPTPlaceholder
->mpPlaceholder
->getSubType() );
286 if( pPPTPlaceholder
->mpPlaceholder
->getTextBody() )
287 pNewTextListStyle
->apply( pPPTPlaceholder
->mpPlaceholder
->getTextBody()->getTextListStyle() );
288 if( pPlaceholderStyle
.get() ) {
289 pNewTextListStyle
->apply( *pPlaceholderStyle
);
290 //pPlaceholderStyle->dump();
293 } else if( !mpPlaceholder
.get() ) {
294 aMasterTextListStyle
.reset();
296 SAL_INFO("oox.ppt","placeholder id: " << (pPlaceholder
.get() ? pPlaceholder
->getId() : "not found"));
299 if ( !sServiceName
.isEmpty() )
301 if ( !aMasterTextListStyle
.get() )
303 bool isOther
= !getTextBody().get() && !sServiceName
.equalsAscii("com.sun.star.drawing.GroupShape");
304 TextListStylePtr aSlideStyle
= isOther
? rSlidePersist
.getOtherTextStyle() : rSlidePersist
.getDefaultTextStyle();
305 // Combine from MasterSlide details as well.
306 if( rSlidePersist
.getMasterPersist().get() )
308 aMasterTextListStyle
= isOther
? rSlidePersist
.getMasterPersist()->getOtherTextStyle() : rSlidePersist
.getMasterPersist()->getDefaultTextStyle();
309 if( aSlideStyle
.get() )
310 aMasterTextListStyle
->apply( *aSlideStyle
.get() );
314 aMasterTextListStyle
= aSlideStyle
;
318 if( aMasterTextListStyle
.get() && getTextBody().get() ) {
319 TextListStylePtr
aCombinedTextListStyle (new TextListStyle());
321 aCombinedTextListStyle
->apply( *aMasterTextListStyle
.get() );
323 if( mpPlaceholder
.get() && mpPlaceholder
->getTextBody().get() )
324 aCombinedTextListStyle
->apply( mpPlaceholder
->getTextBody()->getTextListStyle() );
325 aCombinedTextListStyle
->apply( getTextBody()->getTextListStyle() );
327 setMasterTextListStyle( aCombinedTextListStyle
);
329 setMasterTextListStyle( aMasterTextListStyle
);
331 Reference
< XShape
> xShape( createAndInsert( rFilterBase
, sServiceName
, pTheme
, rxShapes
, pShapeRect
, bClearText
, mpPlaceholder
.get() != NULL
, aTransformation
, getFillProperties() ) );
332 if ( !rSlidePersist
.isMasterPage() && rSlidePersist
.getPage().is() && ( (sal_Int32
)mnSubType
== XML_title
) )
337 Reference
< XTextRange
> xText( xShape
, UNO_QUERY_THROW
);
338 aTitleText
= xText
->getString();
339 if ( !aTitleText
.isEmpty() && ( aTitleText
.getLength() < 64 ) ) // just a magic value, but we don't want to set slide names which are too long
341 Reference
< container::XNamed
> xName( rSlidePersist
.getPage(), UNO_QUERY_THROW
);
342 xName
->setName( aTitleText
);
345 catch( uno::Exception
& )
352 // bnc#705982 - if optional model id reference is
353 // there, use that to obtain target shape
354 if( !msModelId
.isEmpty() )
356 (*pShapeMap
)[ msModelId
] = shared_from_this();
358 else if( !msId
.isEmpty() )
360 (*pShapeMap
)[ msId
] = shared_from_this();
364 // if this is a group shape, we have to add also each child shape
365 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY
);
367 addChildren( rFilterBase
, *this, pTheme
, xShapes
, pShapeRect
? *pShapeRect
: awt::Rectangle( maPosition
.X
, maPosition
.Y
, maSize
.Width
, maSize
.Height
), pShapeMap
, aTransformation
);
371 catch( const Exception
& )
376 void PPTShape::applyShapeReference( const oox::drawingml::Shape
& rReferencedShape
, bool bUseText
)
378 Shape::applyShapeReference( rReferencedShape
, bUseText
);
381 oox::drawingml::ShapePtr
PPTShape::findPlaceholder( const sal_Int32 nMasterPlaceholder
, std::vector
< oox::drawingml::ShapePtr
>& rShapes
, bool bMasterOnly
)
383 oox::drawingml::ShapePtr aShapePtr
;
384 std::vector
< oox::drawingml::ShapePtr
>::reverse_iterator
aRevIter( rShapes
.rbegin() );
385 while( aRevIter
!= rShapes
.rend() )
387 if ( (*aRevIter
)->getSubType() == nMasterPlaceholder
&&
389 ( dynamic_cast< PPTShape
* >( (*aRevIter
).get() ) && dynamic_cast< PPTShape
* >( (*aRevIter
).get() )->getShapeLocation() == Master
) ) )
391 aShapePtr
= *aRevIter
;
394 std::vector
< oox::drawingml::ShapePtr
>& rChildren
= (*aRevIter
)->getChildren();
395 aShapePtr
= findPlaceholder( nMasterPlaceholder
, rChildren
, bMasterOnly
);
396 if ( aShapePtr
.get() )
403 oox::drawingml::ShapePtr
PPTShape::findPlaceholderByIndex( const sal_Int32 nIdx
, std::vector
< oox::drawingml::ShapePtr
>& rShapes
, bool bMasterOnly
)
405 oox::drawingml::ShapePtr aShapePtr
;
407 std::vector
< oox::drawingml::ShapePtr
>::reverse_iterator
aRevIter( rShapes
.rbegin() );
408 while( aRevIter
!= rShapes
.rend() )
410 if ( (*aRevIter
)->getSubTypeIndex().has() && (*aRevIter
)->getSubTypeIndex().get() == nIdx
&&
412 ( dynamic_cast< PPTShape
* >( (*aRevIter
).get() ) && dynamic_cast< PPTShape
* >( (*aRevIter
).get() )->getShapeLocation() == Master
) ) )
414 aShapePtr
= *aRevIter
;
417 std::vector
< oox::drawingml::ShapePtr
>& rChildren
= (*aRevIter
)->getChildren();
418 aShapePtr
= findPlaceholderByIndex( nIdx
, rChildren
, bMasterOnly
);
419 if ( aShapePtr
.get() )
428 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */