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 814 : PPTShape::PPTShape( const oox::ppt::ShapeLocation eShapeLocation, const sal_Char* pServiceName )
45 : : Shape( pServiceName )
46 : , meShapeLocation( eShapeLocation )
47 814 : , mbReferenced( false )
48 : {
49 814 : }
50 :
51 1628 : PPTShape::~PPTShape()
52 : {
53 1628 : }
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 3 : oox::drawingml::TextListStylePtr PPTShape::getSubTypeTextListStyle( const SlidePersist& rSlidePersist, sal_Int32 nSubType )
84 : {
85 3 : oox::drawingml::TextListStylePtr pTextListStyle;
86 :
87 : SAL_INFO("oox.ppt", "subtype style: " << lclDebugSubType( nSubType ) );
88 :
89 3 : 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 3 : if ( rSlidePersist.isNotesPage() )
101 0 : pTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getNotesTextStyle() : rSlidePersist.getNotesTextStyle();
102 : else
103 3 : pTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
104 3 : break;
105 : }
106 :
107 3 : return pTextListStyle;
108 : }
109 :
110 507 : 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 507 : if ( mnSubType && ( meShapeLocation == Master ) )
122 623 : return;
123 : try
124 : {
125 391 : OUString sServiceName( msServiceName );
126 391 : if( !sServiceName.isEmpty() )
127 : {
128 391 : oox::drawingml::TextListStylePtr aMasterTextListStyle;
129 782 : Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
130 391 : sal_Bool bClearText = sal_False;
131 :
132 779 : if ( sServiceName != "com.sun.star.drawing.GraphicObjectShape" &&
133 388 : sServiceName != "com.sun.star.drawing.OLE2Shape" )
134 : {
135 386 : const OUString sOutlinerShapeService( "com.sun.star.presentation.OutlinerShape" );
136 : SAL_INFO("oox.ppt","has master: " << std::hex << rSlidePersist.getMasterPersist().get());
137 386 : switch( mnSubType )
138 : {
139 : case XML_ctrTitle :
140 : case XML_title :
141 : {
142 27 : sServiceName = "com.sun.star.presentation.TitleTextShape";
143 27 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
144 : }
145 27 : break;
146 : case XML_subTitle :
147 : {
148 16 : if ( ( meShapeLocation == Master ) || ( meShapeLocation == Layout ) )
149 14 : sServiceName = OUString();
150 : else {
151 2 : sServiceName = "com.sun.star.presentation.SubtitleShape";
152 2 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getTitleTextStyle() : rSlidePersist.getTitleTextStyle();
153 : }
154 : }
155 16 : break;
156 : case XML_obj :
157 : {
158 7 : sServiceName = sOutlinerShapeService;
159 7 : aMasterTextListStyle = rSlidePersist.getMasterPersist().get() ? rSlidePersist.getMasterPersist()->getBodyTextStyle() : rSlidePersist.getBodyTextStyle();
160 : }
161 7 : break;
162 : case XML_body :
163 : {
164 6 : if ( rSlidePersist.isNotesPage() )
165 : {
166 5 : sServiceName = "com.sun.star.presentation.NotesShape";
167 5 : 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 6 : break;
176 : case XML_dt :
177 16 : sServiceName = "com.sun.star.presentation.DateTimeShape";
178 16 : bClearText = sal_True;
179 16 : 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 17 : sServiceName = "com.sun.star.presentation.FooterShape";
186 17 : bClearText = sal_True;
187 17 : break;
188 : case XML_sldNum :
189 22 : sServiceName = "com.sun.star.presentation.SlideNumberShape";
190 22 : bClearText = sal_True;
191 22 : break;
192 : case XML_sldImg :
193 4 : sServiceName = "com.sun.star.presentation.PageShape";
194 4 : 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 271 : if ( mnSubType && meShapeLocation == Layout )
221 0 : sServiceName = sOutlinerShapeService;
222 271 : break;
223 386 : }
224 : }
225 :
226 : SAL_INFO("oox.ppt","shape service: " << sServiceName);
227 :
228 391 : if( mnSubType && getSubTypeIndex().has() && meShapeLocation == Layout ) {
229 64 : oox::drawingml::ShapePtr pPlaceholder = PPTShape::findPlaceholderByIndex( getSubTypeIndex().get(), rSlidePersist.getShapes()->getChildren(), true );
230 64 : if (!pPlaceholder.get())
231 50 : pPlaceholder = PPTShape::findPlaceholder( mnSubType, rSlidePersist.getShapes()->getChildren(), true );
232 :
233 64 : if (pPlaceholder.get()) {
234 64 : 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 64 : }
251 : }
252 :
253 : // use placeholder index if possible
254 391 : if( mnSubType && getSubTypeIndex().has() && rSlidePersist.getMasterPersist().get() ) {
255 12 : 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 12 : if( rSlidePersist.isNotesPage() && pPlaceholder.get() && pPlaceholder->getSubType() != getSubType() )
258 3 : pPlaceholder.reset();
259 :
260 12 : if( pPlaceholder.get()) {
261 : SAL_INFO("oox.ppt","found placeholder with index: " << getSubTypeIndex().get() << " and type: " << lclDebugSubType( mnSubType ));
262 : }
263 12 : if( pPlaceholder.get() ) {
264 4 : PPTShape* pPPTPlaceholder = dynamic_cast< PPTShape* >( pPlaceholder.get() );
265 4 : TextListStylePtr pNewTextListStyle ( new TextListStyle() );
266 :
267 4 : if( pPlaceholder->getTextBody() ) {
268 :
269 4 : pNewTextListStyle->apply( pPlaceholder->getTextBody()->getTextListStyle() );
270 4 : if( pPlaceholder->getMasterTextListStyle().get() )
271 4 : 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 4 : aMasterTextListStyle = pNewTextListStyle;
279 : // SAL_INFO("oox.ppt","combined master text list style");
280 : // aMasterTextListStyle->dump();
281 : }
282 4 : 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 3 : TextListStylePtr pPlaceholderStyle = getSubTypeTextListStyle( rSlidePersist, pPPTPlaceholder->mpPlaceholder->getSubType() );
286 3 : if( pPPTPlaceholder->mpPlaceholder->getTextBody() )
287 3 : pNewTextListStyle->apply( pPPTPlaceholder->mpPlaceholder->getTextBody()->getTextListStyle() );
288 3 : if( pPlaceholderStyle.get() ) {
289 3 : pNewTextListStyle->apply( *pPlaceholderStyle );
290 : //pPlaceholderStyle->dump();
291 3 : }
292 4 : }
293 8 : } else if( !mpPlaceholder.get() ) {
294 1 : aMasterTextListStyle.reset();
295 : }
296 12 : SAL_INFO("oox.ppt","placeholder id: " << (pPlaceholder.get() ? pPlaceholder->getId() : "not found"));
297 : }
298 :
299 391 : if ( !sServiceName.isEmpty() )
300 : {
301 377 : if ( !aMasterTextListStyle.get() )
302 : {
303 334 : bool isOther = !getTextBody().get() && !sServiceName.equalsAscii("com.sun.star.drawing.GroupShape");
304 334 : TextListStylePtr aSlideStyle = isOther ? rSlidePersist.getOtherTextStyle() : rSlidePersist.getDefaultTextStyle();
305 : // Combine from MasterSlide details as well.
306 334 : if( rSlidePersist.getMasterPersist().get() )
307 : {
308 279 : aMasterTextListStyle = isOther ? rSlidePersist.getMasterPersist()->getOtherTextStyle() : rSlidePersist.getMasterPersist()->getDefaultTextStyle();
309 279 : if( aSlideStyle.get() )
310 279 : aMasterTextListStyle->apply( *aSlideStyle.get() );
311 : }
312 : else
313 : {
314 55 : aMasterTextListStyle = aSlideStyle;
315 334 : }
316 : }
317 :
318 377 : if( aMasterTextListStyle.get() && getTextBody().get() ) {
319 171 : TextListStylePtr aCombinedTextListStyle (new TextListStyle());
320 :
321 171 : aCombinedTextListStyle->apply( *aMasterTextListStyle.get() );
322 :
323 171 : if( mpPlaceholder.get() && mpPlaceholder->getTextBody().get() )
324 98 : aCombinedTextListStyle->apply( mpPlaceholder->getTextBody()->getTextListStyle() );
325 171 : aCombinedTextListStyle->apply( getTextBody()->getTextListStyle() );
326 :
327 171 : setMasterTextListStyle( aCombinedTextListStyle );
328 : } else
329 206 : setMasterTextListStyle( aMasterTextListStyle );
330 :
331 377 : Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, bClearText, mpPlaceholder.get() != NULL, aTransformation, getFillProperties() ) );
332 377 : if ( !rSlidePersist.isMasterPage() && rSlidePersist.getPage().is() && ( (sal_Int32)mnSubType == XML_title ) )
333 : {
334 : try
335 : {
336 3 : OUString aTitleText;
337 6 : Reference< XTextRange > xText( xShape, UNO_QUERY_THROW );
338 3 : aTitleText = xText->getString();
339 3 : 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 3 : Reference< container::XNamed > xName( rSlidePersist.getPage(), UNO_QUERY_THROW );
342 3 : xName->setName( aTitleText );
343 3 : }
344 : }
345 0 : catch( uno::Exception& )
346 : {
347 :
348 : }
349 : }
350 377 : if( pShapeMap )
351 : {
352 : // bnc#705982 - if optional model id reference is
353 : // there, use that to obtain target shape
354 377 : if( !msModelId.isEmpty() )
355 : {
356 0 : (*pShapeMap)[ msModelId ] = shared_from_this();
357 : }
358 377 : else if( !msId.isEmpty() )
359 : {
360 377 : (*pShapeMap)[ msId ] = shared_from_this();
361 : }
362 : }
363 :
364 : // if this is a group shape, we have to add also each child shape
365 754 : Reference< XShapes > xShapes( xShape, UNO_QUERY );
366 377 : if ( xShapes.is() )
367 385 : addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap, aTransformation );
368 391 : }
369 391 : }
370 : }
371 0 : catch( const Exception& )
372 : {
373 : }
374 : }
375 :
376 115 : void PPTShape::applyShapeReference( const oox::drawingml::Shape& rReferencedShape, bool bUseText )
377 : {
378 115 : Shape::applyShapeReference( rReferencedShape, bUseText );
379 115 : }
380 :
381 440 : oox::drawingml::ShapePtr PPTShape::findPlaceholder( const sal_Int32 nMasterPlaceholder, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
382 : {
383 440 : oox::drawingml::ShapePtr aShapePtr;
384 440 : std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
385 1218 : while( aRevIter != rShapes.rend() )
386 : {
387 592 : if ( (*aRevIter)->getSubType() == nMasterPlaceholder &&
388 201 : ( !bMasterOnly ||
389 200 : ( dynamic_cast< PPTShape* >( (*aRevIter).get() ) && dynamic_cast< PPTShape* >( (*aRevIter).get() )->getShapeLocation() == Master ) ) )
390 : {
391 51 : aShapePtr = *aRevIter;
392 51 : break;
393 : }
394 389 : std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
395 389 : aShapePtr = findPlaceholder( nMasterPlaceholder, rChildren, bMasterOnly );
396 389 : if ( aShapePtr.get() )
397 51 : break;
398 338 : ++aRevIter;
399 : }
400 440 : return aShapePtr;
401 : }
402 :
403 1345 : oox::drawingml::ShapePtr PPTShape::findPlaceholderByIndex( const sal_Int32 nIdx, std::vector< oox::drawingml::ShapePtr >& rShapes, bool bMasterOnly )
404 : {
405 1345 : oox::drawingml::ShapePtr aShapePtr;
406 :
407 1345 : std::vector< oox::drawingml::ShapePtr >::reverse_iterator aRevIter( rShapes.rbegin() );
408 3841 : while( aRevIter != rShapes.rend() )
409 : {
410 1383 : if ( (*aRevIter)->getSubTypeIndex().has() && (*aRevIter)->getSubTypeIndex().get() == nIdx &&
411 184 : ( !bMasterOnly ||
412 156 : ( dynamic_cast< PPTShape* >( (*aRevIter).get() ) && dynamic_cast< PPTShape* >( (*aRevIter).get() )->getShapeLocation() == Master ) ) )
413 : {
414 42 : aShapePtr = *aRevIter;
415 42 : break;
416 : }
417 1193 : std::vector< oox::drawingml::ShapePtr >& rChildren = (*aRevIter)->getChildren();
418 1193 : aShapePtr = findPlaceholderByIndex( nIdx, rChildren, bMasterOnly );
419 1193 : if ( aShapePtr.get() )
420 42 : break;
421 1151 : ++aRevIter;
422 : }
423 1345 : return aShapePtr;
424 : }
425 :
426 177 : } }
427 :
428 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|