Line data Source code
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 :
20 : #include "oox/ppt/pptshape.hxx"
21 : #include "oox/core/xmlfilterbase.hxx"
22 : #include "oox/drawingml/textbody.hxx"
23 :
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"
31 :
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;
41 :
42 : namespace oox { namespace ppt {
43 :
44 198 : PPTShape::PPTShape( const oox::ppt::ShapeLocation eShapeLocation, const sal_Char* pServiceName )
45 : : Shape( pServiceName )
46 : , meShapeLocation( eShapeLocation )
47 198 : , mbReferenced( sal_False )
48 : {
49 198 : }
50 :
51 396 : PPTShape::~PPTShape()
52 : {
53 396 : }
54 :
55 0 : static const char* lclDebugSubType( sal_Int32 nType )
56 : {
57 0 : switch (nType) {
58 : case XML_ctrTitle :
59 0 : return "ctrTitle";
60 : case XML_title :
61 0 : return "title";
62 : case XML_subTitle :
63 0 : return "subTitle";
64 : case XML_obj :
65 0 : return "obj";
66 : case XML_body :
67 0 : return "body";
68 : case XML_dt :
69 0 : return "dt";
70 : case XML_hdr :
71 0 : return "hdr";
72 : case XML_ftr :
73 0 : return "frt";
74 : case XML_sldNum :
75 0 : return "sldNum";
76 : case XML_sldImg :
77 0 : return "sldImg";
78 : }
79 :
80 0 : return "unknown - please extend lclDebugSubType";
81 : }
82 :
83 1 : oox::drawingml::TextListStylePtr PPTShape::getSubTypeTextListStyle( const SlidePersist& rSlidePersist, sal_Int32 nSubType )
84 : {
85 1 : oox::drawingml::TextListStylePtr pTextListStyle;
86 :
87 : SAL_INFO("oox.ppt", "subtype style: " << lclDebugSubType( nSubType ) );
88 :
89 1 : switch( nSubType )
90 : {
91 : case XML_ctrTitle :
92 : case XML_title :
93 : case XML_subTitle :
94 0 : pTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
95 0 : break;
96 : case XML_obj :
97 0 : pTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
98 0 : break;
99 : case XML_body :
100 1 : if ( rSlidePersist.isNotesPage() )
101 0 : pTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
102 : else
103 1 : pTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
104 1 : break;
105 : }
106 :
107 1 : return pTextListStyle;
108 : }
109 :
110 132 : 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 )
118 : {
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 132 : if ( mnSubType && ( meShapeLocation == Master ) )
122 164 : return;
123 : try
124 : {
125 100 : OUString sServiceName( msServiceName );
126 100 : if( !sServiceName.isEmpty() )
127 : {
128 100 : oox::drawingml::TextListStylePtr aMasterTextListStyle;
129 200 : Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
130 100 : sal_Bool bClearText = sal_False;
131 :
132 199 : if ( sServiceName != "com.sun.star.drawing.GraphicObjectShape" &&
133 99 : sServiceName != "com.sun.star.drawing.OLE2Shape" )
134 : {
135 99 : const OUString sOutlinerShapeService( "com.sun.star.presentation.OutlinerShape" );
136 : SAL_INFO("oox.ppt","has master: " << std::hex << rSlidePersist.getMasterPersist().get());
137 99 : switch( mnSubType )
138 : {
139 : case XML_ctrTitle :
140 : case XML_title :
141 : {
142 7 : sServiceName = "com.sun.star.presentation.TitleTextShape";
143 7 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
144 : }
145 7 : break;
146 : case XML_subTitle :
147 : {
148 2 : if ( ( meShapeLocation == Master ) || ( meShapeLocation == Layout ) )
149 2 : sServiceName = OUString();
150 : else {
151 0 : sServiceName = "com.sun.star.presentation.SubtitleShape";
152 0 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
153 : }
154 : }
155 2 : break;
156 : case XML_obj :
157 : {
158 3 : sServiceName = sOutlinerShapeService;
159 3 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
160 : }
161 3 : break;
162 : case XML_body :
163 : {
164 3 : if ( rSlidePersist.isNotesPage() )
165 : {
166 2 : sServiceName = "com.sun.star.presentation.NotesShape";
167 2 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
168 : }
169 : else
170 : {
171 1 : sServiceName = sOutlinerShapeService;
172 1 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
173 : }
174 : }
175 3 : break;
176 : case XML_dt :
177 4 : sServiceName = "com.sun.star.presentation.DateTimeShape";
178 4 : bClearText = sal_True;
179 4 : break;
180 : case XML_hdr :
181 0 : sServiceName = "com.sun.star.presentation.HeaderShape";
182 0 : bClearText = sal_True;
183 0 : break;
184 : case XML_ftr :
185 5 : sServiceName = "com.sun.star.presentation.FooterShape";
186 5 : bClearText = sal_True;
187 5 : break;
188 : case XML_sldNum :
189 8 : sServiceName = "com.sun.star.presentation.SlideNumberShape";
190 8 : bClearText = sal_True;
191 8 : break;
192 : case XML_sldImg :
193 2 : sServiceName = "com.sun.star.presentation.PageShape";
194 2 : break;
195 : case XML_chart :
196 0 : if ( meShapeLocation == Layout )
197 0 : sServiceName = sOutlinerShapeService;
198 : else
199 0 : sServiceName = "com.sun.star.presentation.ChartShape";
200 0 : break;
201 : case XML_tbl :
202 0 : if ( meShapeLocation == Layout )
203 0 : sServiceName = sOutlinerShapeService;
204 : else
205 0 : sServiceName = "com.sun.star.presentation.TableShape";
206 0 : break;
207 : case XML_pic :
208 0 : if ( meShapeLocation == Layout )
209 0 : sServiceName = sOutlinerShapeService;
210 : else
211 0 : sServiceName = "com.sun.star.presentation.GraphicObjectShape";
212 0 : break;
213 : case XML_media :
214 0 : if ( meShapeLocation == Layout )
215 0 : sServiceName = sOutlinerShapeService;
216 : else
217 0 : sServiceName = "com.sun.star.presentation.MediaShape";
218 0 : break;
219 : default:
220 65 : if ( mnSubType && meShapeLocation == Layout )
221 0 : sServiceName = sOutlinerShapeService;
222 65 : break;
223 99 : }
224 : }
225 :
226 : SAL_INFO("oox.ppt","shape service: " << sServiceName);
227 :
228 100 : if( mnSubType && getSubTypeIndex().has() && meShapeLocation == Layout ) {
229 17 : oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex( getSubTypeIndex().get(), rSlidePersist.getShapes()->getChildren(), true );
230 17 : if (!pPlaceholder.get())
231 14 : pPlaceholder = PPTShape::findPlaceholder( mnSubType, rSlidePersist.getShapes()->getChildren(), true );
232 :
233 17 : if (pPlaceholder.get()) {
234 17 : if( maSize.Width == 0 || maSize.Height == 0 ) {
235 0 : awt::Size aSize = maSize;
236 0 : if( maSize.Width == 0 )
237 0 : aSize.Width = pPlaceholder->getSize().Width;
238 0 : if( maSize.Height == 0 )
239 0 : aSize.Height = pPlaceholder->getSize().Height;
240 0 : setSize( aSize );
241 0 : if ( maPosition.X == 0 || maPosition.Y == 0 ) {
242 0 : awt::Point aPosition = maPosition;
243 0 : if( maPosition.X == 0 )
244 0 : aPosition.X = pPlaceholder->getPosition().X;
245 0 : if( maPosition.Y == 0 )
246 0 : aPosition.Y = pPlaceholder->getPosition().Y;
247 0 : setPosition( aPosition );
248 : }
249 : }
250 17 : }
251 : }
252 :
253 : // use placeholder index if possible
254 100 : if( mnSubType && getSubTypeIndex().has() && rSlidePersist.getMasterPersist().get() ) {
255 7 : 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 7 : if( rSlidePersist.isNotesPage() && pPlaceholder.get() && pPlaceholder->getSubType() != getSubType() )
258 2 : pPlaceholder.reset();
259 :
260 7 : if( pPlaceholder.get()) {
261 : SAL_INFO("oox.ppt","found placeholder with index: " << getSubTypeIndex().get() << " and type: " << lclDebugSubType( mnSubType ));
262 : }
263 7 : if( pPlaceholder.get() ) {
264 2 : PPTShape* pPPTPlaceholder = dynamic_cast< PPTShape* >( pPlaceholder.get() );
265 2 : TextListStylePtr pNewTextListStyle ( new TextListStyle() );
266 :
267 2 : if( pPlaceholder->getTextBody() ) {
268 :
269 2 : pNewTextListStyle->apply( pPlaceholder->getTextBody()->getTextListStyle() );
270 2 : if( pPlaceholder->getMasterTextListStyle().get() )
271 2 : pNewTextListStyle->apply( *pPlaceholder->getMasterTextListStyle() );
272 :
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();
277 :
278 2 : aMasterTextListStyle = pNewTextListStyle;
279 : // SAL_INFO("oox.ppt","combined master text list style");
280 : // aMasterTextListStyle->dump();
281 : }
282 2 : 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 1 : TextListStylePtr pPlaceholderStyle = getSubTypeTextListStyle( rSlidePersist, pPPTPlaceholder->mpPlaceholder->getSubType() );
286 1 : if( pPPTPlaceholder->mpPlaceholder->getTextBody() )
287 1 : pNewTextListStyle->apply( pPPTPlaceholder->mpPlaceholder->getTextBody()->getTextListStyle() );
288 1 : if( pPlaceholderStyle.get() ) {
289 1 : pNewTextListStyle->apply( *pPlaceholderStyle );
290 : //pPlaceholderStyle->dump();
291 1 : }
292 2 : }
293 5 : } else if( !mpPlaceholder.get() ) {
294 1 : aMasterTextListStyle.reset();
295 : }
296 7 : SAL_INFO("oox.ppt","placeholder id: " << (pPlaceholder.get() ? pPlaceholder->getId() : "not found"));
297 : }
298 :
299 100 : if ( !sServiceName.isEmpty() )
300 : {
301 98 : if ( !aMasterTextListStyle.get() )
302 : {
303 84 : bool isOther = !getTextBody().get() && !sServiceName.equalsAscii("com.sun.star.drawing.GroupShape");
304 84 : TextListStylePtr aSlideStyle = isOther ? rSlidePersist.getOtherTextStyle() : rSlidePersist.getDefaultTextStyle();
305 : // Combine from MasterSlide details as well.
306 84 : if( rSlidePersist.getMasterPersist().get() )
307 : {
308 70 : aMasterTextListStyle = isOther ? rSlidePersist.getMasterPersist()->getOtherTextStyle() : rSlidePersist.getMasterPersist()->getDefaultTextStyle();
309 70 : if( aSlideStyle.get() )
310 70 : aMasterTextListStyle->apply( *aSlideStyle.get() );
311 : }
312 : else
313 : {
314 14 : aMasterTextListStyle = aSlideStyle;
315 84 : }
316 : }
317 :
318 98 : if( aMasterTextListStyle.get() && getTextBody().get() ) {
319 91 : TextListStylePtr aCombinedTextListStyle (new TextListStyle());
320 :
321 91 : aCombinedTextListStyle->apply( *aMasterTextListStyle.get() );
322 :
323 91 : if( mpPlaceholder.get() && mpPlaceholder->getTextBody().get() )
324 30 : aCombinedTextListStyle->apply( mpPlaceholder->getTextBody()->getTextListStyle() );
325 91 : aCombinedTextListStyle->apply( getTextBody()->getTextListStyle() );
326 :
327 91 : setMasterTextListStyle( aCombinedTextListStyle );
328 : } else
329 7 : setMasterTextListStyle( aMasterTextListStyle );
330 :
331 98 : Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, bClearText, mpPlaceholder.get() != NULL, aTransformation, getFillProperties() ) );
332 98 : if ( !rSlidePersist.isMasterPage() && rSlidePersist.getPage().is() && ( (sal_Int32)mnSubType == XML_title ) )
333 : {
334 : try
335 : {
336 1 : OUString aTitleText;
337 2 : Reference< XTextRange > xText( xShape, UNO_QUERY_THROW );
338 1 : aTitleText = xText->getString();
339 1 : if ( !aTitleText.isEmpty() && ( aTitleText.getLength() < 64 ) ) // just a magic value, but we don't want to set slide names which are too long
340 : {
341 1 : Reference< container::XNamed > xName( rSlidePersist.getPage(), UNO_QUERY_THROW );
342 1 : xName->setName( aTitleText );
343 1 : }
344 : }
345 0 : catch( uno::Exception& )
346 : {
347 :
348 : }
349 : }
350 98 : if( pShapeMap )
351 : {
352 : // bnc#705982 - if optional model id reference is
353 : // there, use that to obtain target shape
354 98 : if( !msModelId.isEmpty() )
355 : {
356 0 : (*pShapeMap)[ msModelId ] = shared_from_this();
357 : }
358 98 : else if( !msId.isEmpty() )
359 : {
360 98 : (*pShapeMap)[ msId ] = shared_from_this();
361 : }
362 : }
363 :
364 : // if this is a group shape, we have to add also each child shape
365 196 : Reference< XShapes > xShapes( xShape, UNO_QUERY );
366 98 : if ( xShapes.is() )
367 99 : addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap, aTransformation );
368 100 : }
369 100 : }
370 : }
371 0 : catch( const Exception& )
372 : {
373 : }
374 : }
375 :
376 33 : void PPTShape::applyShapeReference( const oox::drawingml::Shape& rReferencedShape, bool bUseText )
377 : {
378 33 : Shape::applyShapeReference( rReferencedShape, bUseText );
379 33 : }
380 :
381 112 : oox::drawingml::ShapePtr PPTShape::findPlaceholder( const sal_Int32 nMasterPlaceholder, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
382 : {
383 112 : oox::drawingml::ShapePtr aShapePtr;
384 112 : std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
385 308 : while( aRevIter != rShapes.rend() )
386 : {
387 154 : if ( (*aRevIter)->getSubType() == nMasterPlaceholder &&
388 56 : ( !bMasterOnly ||
389 56 : ( dynamic_cast< PPTShape* >( (*aRevIter).get() ) && dynamic_cast< PPTShape* >( (*aRevIter).get() )->getShapeLocation() == Master ) ) )
390 : {
391 14 : aShapePtr = *aRevIter;
392 14 : break;
393 : }
394 98 : std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
395 98 : aShapePtr = findPlaceholder( nMasterPlaceholder, rChildren, bMasterOnly );
396 98 : if ( aShapePtr.get() )
397 14 : break;
398 84 : ++aRevIter;
399 : }
400 112 : return aShapePtr;
401 : }
402 :
403 390 : oox::drawingml::ShapePtr PPTShape::findPlaceholderByIndex( const sal_Int32 nIdx, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
404 : {
405 390 : oox::drawingml::ShapePtr aShapePtr;
406 :
407 390 : std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
408 1108 : while( aRevIter != rShapes.rend() )
409 : {
410 401 : if ( (*aRevIter)->getSubTypeIndex().has() && (*aRevIter)->getSubTypeIndex().get() == nIdx &&
411 51 : ( !bMasterOnly ||
412 40 : ( dynamic_cast< PPTShape* >( (*aRevIter).get() ) && dynamic_cast< PPTShape* >( (*aRevIter).get() )->getShapeLocation() == Master ) ) )
413 : {
414 14 : aShapePtr = *aRevIter;
415 14 : break;
416 : }
417 342 : std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
418 342 : aShapePtr = findPlaceholderByIndex( nIdx, rChildren, bMasterOnly );
419 342 : if ( aShapePtr.get() )
420 14 : break;
421 328 : ++aRevIter;
422 : }
423 390 : return aShapePtr;
424 : }
425 :
426 141 : } }
427 :
428 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|