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