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/drawingml/shape.hxx"
21 : #include "oox/drawingml/customshapeproperties.hxx"
22 : #include "oox/drawingml/theme.hxx"
23 : #include "oox/drawingml/fillproperties.hxx"
24 : #include "oox/drawingml/lineproperties.hxx"
25 : #include "oox/drawingml/effectproperties.hxx"
26 : #include "oox/drawingml/shapepropertymap.hxx"
27 : #include "oox/drawingml/textbody.hxx"
28 : #include "oox/drawingml/table/tableproperties.hxx"
29 : #include "oox/drawingml/chart/chartconverter.hxx"
30 : #include "oox/drawingml/chart/chartspacefragment.hxx"
31 : #include "oox/drawingml/chart/chartspacemodel.hxx"
32 : #include "oox/vml/vmldrawing.hxx"
33 : #include "oox/vml/vmlshape.hxx"
34 : #include "oox/vml/vmlshapecontainer.hxx"
35 : #include "oox/core/xmlfilterbase.hxx"
36 : #include "oox/helper/graphichelper.hxx"
37 : #include "oox/helper/propertyset.hxx"
38 : #include "oox/helper/modelobjecthelper.hxx"
39 :
40 : #include <tools/gen.hxx>
41 : #include <tools/mapunit.hxx>
42 : #include <editeng/unoprnms.hxx>
43 : #include <com/sun/star/awt/Size.hpp>
44 : #include <com/sun/star/graphic/XGraphic.hpp>
45 : #include <com/sun/star/container/XNamed.hpp>
46 : #include <com/sun/star/container/XNameContainer.hpp>
47 : #include <com/sun/star/beans/XMultiPropertySet.hpp>
48 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
49 : #include <com/sun/star/xml/AttributeData.hpp>
50 : #include <com/sun/star/drawing/HomogenMatrix3.hpp>
51 : #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
52 : #include <com/sun/star/drawing/GraphicExportFilter.hpp>
53 : #include <com/sun/star/text/XText.hpp>
54 : #include <com/sun/star/table/BorderLine2.hpp>
55 : #include <com/sun/star/table/ShadowFormat.hpp>
56 : #include <com/sun/star/chart2/XChartDocument.hpp>
57 : #include <com/sun/star/style/ParagraphAdjust.hpp>
58 : #include <com/sun/star/io/XOutputStream.hpp>
59 :
60 : #include <basegfx/point/b2dpoint.hxx>
61 : #include <basegfx/polygon/b2dpolygon.hxx>
62 : #include <basegfx/matrix/b2dhommatrix.hxx>
63 : #include <com/sun/star/document/XActionLockable.hpp>
64 : #include <com/sun/star/chart2/data/XDataReceiver.hpp>
65 : #include <svl/outstrm.hxx>
66 : #include <unotools/streamwrap.hxx>
67 : #include <unotools/fltrcfg.hxx>
68 : #include <vcl/graph.hxx>
69 : #include <vcl/graphicfilter.hxx>
70 : #include <vcl/svapp.hxx>
71 :
72 : using namespace ::oox::core;
73 : using namespace ::com::sun::star;
74 : using namespace ::com::sun::star::uno;
75 : using namespace ::com::sun::star::beans;
76 : using namespace ::com::sun::star::frame;
77 : using namespace ::com::sun::star::text;
78 : using namespace ::com::sun::star::drawing;
79 : using namespace ::com::sun::star::style;
80 :
81 : namespace oox { namespace drawingml {
82 :
83 : #define PUT_PROP( aProperties, nPos, sPropName, aPropValue ) \
84 : aProperties[nPos].Name = sPropName; \
85 : aProperties[nPos].Value = Any( aPropValue );
86 :
87 0 : Shape::Shape( const sal_Char* pServiceName, bool bDefaultHeight )
88 : : mbIsChild( false )
89 0 : , mpLinePropertiesPtr( new LineProperties )
90 0 : , mpFillPropertiesPtr( new FillProperties )
91 0 : , mpGraphicPropertiesPtr( new GraphicProperties )
92 0 : , mpCustomShapePropertiesPtr( new CustomShapeProperties )
93 0 : , mpEffectPropertiesPtr( new EffectProperties )
94 0 : , mpMasterTextListStyle( new TextListStyle )
95 : , mnSubType( 0 )
96 : , meFrameType( FRAMETYPE_GENERIC )
97 : , mnRotation( 0 )
98 : , mbFlipH( false )
99 : , mbFlipV( false )
100 : , mbHidden( false )
101 : , mbHiddenMasterShape( false )
102 : , mbLockedCanvas( false )
103 : , mbWps( false )
104 0 : , maDiagramDoms( 0 )
105 : {
106 0 : if ( pServiceName )
107 0 : msServiceName = OUString::createFromAscii( pServiceName );
108 0 : setDefaults(bDefaultHeight);
109 0 : }
110 :
111 0 : Shape::Shape( const ShapePtr& pSourceShape )
112 : : maChildren()
113 0 : , mbIsChild( pSourceShape->mbIsChild )
114 0 : , mpTextBody(pSourceShape->mpTextBody)
115 0 : , mpLinePropertiesPtr( pSourceShape->mpLinePropertiesPtr )
116 0 : , mpFillPropertiesPtr( pSourceShape->mpFillPropertiesPtr )
117 0 : , mpGraphicPropertiesPtr( pSourceShape->mpGraphicPropertiesPtr )
118 0 : , mpCustomShapePropertiesPtr( pSourceShape->mpCustomShapePropertiesPtr )
119 0 : , mpTablePropertiesPtr( pSourceShape->mpTablePropertiesPtr )
120 0 : , mp3DPropertiesPtr( pSourceShape->mp3DPropertiesPtr )
121 0 : , mpEffectPropertiesPtr (pSourceShape->mpEffectPropertiesPtr)
122 0 : , maShapeProperties( pSourceShape->maShapeProperties )
123 0 : , mpMasterTextListStyle( pSourceShape->mpMasterTextListStyle )
124 : , mxShape()
125 0 : , msServiceName( pSourceShape->msServiceName )
126 0 : , msName( pSourceShape->msName )
127 0 : , msId( pSourceShape->msId )
128 0 : , mnSubType( pSourceShape->mnSubType )
129 0 : , moSubTypeIndex( pSourceShape->moSubTypeIndex )
130 0 : , maShapeStyleRefs( pSourceShape->maShapeStyleRefs )
131 0 : , maSize( pSourceShape->maSize )
132 0 : , maPosition( pSourceShape->maPosition )
133 0 : , meFrameType( pSourceShape->meFrameType )
134 0 : , mnRotation( pSourceShape->mnRotation )
135 0 : , mbFlipH( pSourceShape->mbFlipH )
136 0 : , mbFlipV( pSourceShape->mbFlipV )
137 0 : , mbHidden( pSourceShape->mbHidden )
138 0 : , mbHiddenMasterShape( pSourceShape->mbHiddenMasterShape )
139 0 : , mbLockedCanvas( pSourceShape->mbLockedCanvas )
140 0 : , mbWps( pSourceShape->mbWps )
141 0 : , maDiagramDoms( pSourceShape->maDiagramDoms )
142 0 : {}
143 :
144 :
145 0 : Shape::~Shape()
146 : {
147 0 : }
148 :
149 0 : table::TablePropertiesPtr Shape::getTableProperties()
150 : {
151 0 : if ( !mpTablePropertiesPtr.get() )
152 0 : mpTablePropertiesPtr.reset( new table::TableProperties() );
153 0 : return mpTablePropertiesPtr;
154 : }
155 :
156 0 : void Shape::setDefaults(bool bHeight)
157 : {
158 0 : maDefaultShapeProperties.setProperty(PROP_TextAutoGrowHeight, false);
159 0 : maDefaultShapeProperties.setProperty(PROP_TextWordWrap, true);
160 0 : maDefaultShapeProperties.setProperty(PROP_TextLeftDistance, static_cast< sal_Int32 >( 250 ));
161 0 : maDefaultShapeProperties.setProperty(PROP_TextUpperDistance, static_cast< sal_Int32 >( 125 ));
162 0 : maDefaultShapeProperties.setProperty(PROP_TextRightDistance, static_cast< sal_Int32 >( 250 ));
163 0 : maDefaultShapeProperties.setProperty(PROP_TextLowerDistance, static_cast< sal_Int32 >( 125 ));
164 0 : if (bHeight)
165 0 : maDefaultShapeProperties.setProperty(PROP_CharHeight, static_cast< float >( 18.0 ));
166 0 : maDefaultShapeProperties.setProperty(PROP_TextVerticalAdjust, TextVerticalAdjust_TOP);
167 0 : maDefaultShapeProperties.setProperty(PROP_ParaAdjust, static_cast< sal_Int16 >( ParagraphAdjust_LEFT )); // check for RTL?
168 0 : }
169 :
170 0 : ::oox::vml::OleObjectInfo& Shape::setOleObjectType()
171 : {
172 : OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" );
173 0 : meFrameType = FRAMETYPE_OLEOBJECT;
174 0 : mxOleObjectInfo.reset( new ::oox::vml::OleObjectInfo( true ) );
175 0 : return *mxOleObjectInfo;
176 : }
177 :
178 0 : ChartShapeInfo& Shape::setChartType( bool bEmbedShapes )
179 : {
180 : OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" );
181 0 : meFrameType = FRAMETYPE_CHART;
182 0 : msServiceName = "com.sun.star.drawing.OLE2Shape";
183 0 : mxChartShapeInfo.reset( new ChartShapeInfo( bEmbedShapes ) );
184 0 : return *mxChartShapeInfo;
185 : }
186 :
187 0 : void Shape::setDiagramType()
188 : {
189 : OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" );
190 0 : meFrameType = FRAMETYPE_DIAGRAM;
191 0 : msServiceName = "com.sun.star.drawing.GroupShape";
192 0 : mnSubType = 0;
193 0 : }
194 :
195 0 : void Shape::setTableType()
196 : {
197 : OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" );
198 0 : meFrameType = FRAMETYPE_TABLE;
199 0 : msServiceName = "com.sun.star.drawing.TableShape";
200 0 : mnSubType = 0;
201 0 : }
202 :
203 0 : void Shape::setServiceName( const sal_Char* pServiceName )
204 : {
205 0 : if ( pServiceName )
206 0 : msServiceName = OUString::createFromAscii( pServiceName );
207 0 : }
208 :
209 :
210 0 : const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const
211 : {
212 0 : ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType );
213 0 : return (aIt == maShapeStyleRefs.end()) ? 0 : &aIt->second;
214 : }
215 :
216 0 : void Shape::addShape(
217 : ::oox::core::XmlFilterBase& rFilterBase,
218 : const Theme* pTheme,
219 : const Reference< XShapes >& rxShapes,
220 : basegfx::B2DHomMatrix& aTransformation,
221 : FillProperties& rShapeOrParentShapeFillProps,
222 : const awt::Rectangle* pShapeRect,
223 : ShapeIdMap* pShapeMap )
224 : {
225 : SAL_INFO("oox.drawingml", OSL_THIS_FUNC << " id: " << msId);
226 :
227 : try
228 : {
229 0 : OUString sServiceName( msServiceName );
230 0 : if( !sServiceName.isEmpty() )
231 : {
232 0 : basegfx::B2DHomMatrix aMatrix( aTransformation );
233 0 : Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, false, false, aMatrix, rShapeOrParentShapeFillProps ) );
234 :
235 0 : if( pShapeMap && !msId.isEmpty() )
236 : {
237 0 : (*pShapeMap)[ msId ] = shared_from_this();
238 : }
239 :
240 : // if this is a group shape, we have to add also each child shape
241 0 : Reference< XShapes > xShapes( xShape, UNO_QUERY );
242 0 : if ( xShapes.is() )
243 0 : addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap, aMatrix );
244 :
245 :
246 0 : if( meFrameType == FRAMETYPE_DIAGRAM )
247 : {
248 0 : if( !SvtFilterOptions::Get().IsSmartArt2Shape() )
249 0 : keepDiagramCompatibilityInfo( rFilterBase );
250 0 : }
251 0 : }
252 : }
253 0 : catch( const Exception& e )
254 : {
255 : SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message );
256 : }
257 0 : }
258 :
259 0 : void Shape::setLockedCanvas(bool bLockedCanvas)
260 : {
261 0 : mbLockedCanvas = bLockedCanvas;
262 0 : }
263 :
264 0 : bool Shape::getLockedCanvas()
265 : {
266 0 : return mbLockedCanvas;
267 : }
268 :
269 0 : void Shape::setWps(bool bWps)
270 : {
271 0 : mbWps = bWps;
272 0 : }
273 :
274 0 : bool Shape::getWps()
275 : {
276 0 : return mbWps;
277 : }
278 :
279 0 : void Shape::applyShapeReference( const Shape& rReferencedShape, bool bUseText )
280 : {
281 : SAL_INFO("oox", OSL_THIS_FUNC << "apply shape reference: " << rReferencedShape.msId << " to shape id: " << msId);
282 :
283 0 : if ( rReferencedShape.mpTextBody.get() && bUseText )
284 0 : mpTextBody = TextBodyPtr( new TextBody( *rReferencedShape.mpTextBody.get() ) );
285 : else
286 0 : mpTextBody.reset();
287 0 : maShapeProperties = rReferencedShape.maShapeProperties;
288 0 : mpLinePropertiesPtr = LinePropertiesPtr( new LineProperties( *rReferencedShape.mpLinePropertiesPtr.get() ) );
289 0 : mpFillPropertiesPtr = FillPropertiesPtr( new FillProperties( *rReferencedShape.mpFillPropertiesPtr.get() ) );
290 0 : mpCustomShapePropertiesPtr = CustomShapePropertiesPtr( new CustomShapeProperties( *rReferencedShape.mpCustomShapePropertiesPtr.get() ) );
291 0 : mpTablePropertiesPtr = table::TablePropertiesPtr( rReferencedShape.mpTablePropertiesPtr.get() ? new table::TableProperties( *rReferencedShape.mpTablePropertiesPtr.get() ) : NULL );
292 0 : mpEffectPropertiesPtr = EffectPropertiesPtr( new EffectProperties( *rReferencedShape.mpEffectPropertiesPtr.get() ) );
293 0 : mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) );
294 0 : maShapeStyleRefs = rReferencedShape.maShapeStyleRefs;
295 0 : maSize = rReferencedShape.maSize;
296 0 : maPosition = rReferencedShape.maPosition;
297 0 : mnRotation = rReferencedShape.mnRotation;
298 0 : mbFlipH = rReferencedShape.mbFlipH;
299 0 : mbFlipV = rReferencedShape.mbFlipV;
300 0 : mbHidden = rReferencedShape.mbHidden;
301 0 : }
302 :
303 0 : void Shape::addChildren( ::oox::core::XmlFilterBase& rFilterBase,
304 : const Theme* pTheme,
305 : const Reference< XShapes >& rxShapes,
306 : basegfx::B2DHomMatrix& aTransformation,
307 : const awt::Rectangle* pShapeRect,
308 : ShapeIdMap* pShapeMap )
309 : {
310 : addChildren(rFilterBase, *this, pTheme, rxShapes,
311 : pShapeRect ?
312 : *pShapeRect :
313 : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ),
314 0 : pShapeMap, aTransformation);
315 0 : }
316 :
317 : struct ActionLockGuard
318 : {
319 0 : explicit ActionLockGuard(Reference<drawing::XShape> const& xShape)
320 0 : : m_xLockable(xShape, UNO_QUERY)
321 : {
322 0 : if (m_xLockable.is()) {
323 0 : m_xLockable->addActionLock();
324 : }
325 0 : }
326 0 : ~ActionLockGuard()
327 0 : {
328 0 : if (m_xLockable.is()) {
329 0 : m_xLockable->removeActionLock();
330 : }
331 0 : }
332 : private:
333 : Reference<document::XActionLockable> m_xLockable;
334 : };
335 :
336 : // for group shapes, the following method is also adding each child
337 0 : void Shape::addChildren(
338 : XmlFilterBase& rFilterBase,
339 : Shape& rMaster,
340 : const Theme* pTheme,
341 : const Reference< XShapes >& rxShapes,
342 : const awt::Rectangle&,
343 : ShapeIdMap* pShapeMap,
344 : basegfx::B2DHomMatrix& aTransformation )
345 : {
346 0 : basegfx::B2DHomMatrix aChildTransformation;
347 :
348 0 : aChildTransformation.translate(-maChPosition.X, -maChPosition.Y);
349 0 : aChildTransformation.scale(1/(maChSize.Width ? maChSize.Width : 1.0), 1/(maChSize.Height ? maChSize.Height : 1.0));
350 :
351 : // Child position and size is typically non-zero, but it's allowed to have
352 : // it like that, and in that case Word ignores the parent transformation
353 : // (excluding translate component).
354 0 : if (!mbWps || maChPosition.X || maChPosition.Y || maChSize.Width || maChSize.Height)
355 : {
356 0 : aChildTransformation *= aTransformation;
357 : }
358 : else
359 : {
360 0 : basegfx::B2DVector aScale, aTranslate;
361 : double fRotate, fShearX;
362 0 : aTransformation.decompose(aScale, aTranslate, fRotate, fShearX);
363 0 : aChildTransformation.translate(aTranslate.getX(), aTranslate.getY());
364 : }
365 :
366 : SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "parent matrix:\n"
367 : << aChildTransformation.get(0, 0) << " "
368 : << aChildTransformation.get(0, 1) << " "
369 : << aChildTransformation.get(0, 2) << "\n"
370 : << aChildTransformation.get(1, 0) << " "
371 : << aChildTransformation.get(1, 1) << " "
372 : << aChildTransformation.get(1, 2) << "\n"
373 : << aChildTransformation.get(2, 0) << " "
374 : << aChildTransformation.get(2, 1) << " "
375 : << aChildTransformation.get(2, 2));
376 :
377 0 : std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() );
378 0 : while( aIter != rMaster.maChildren.end() ) {
379 0 : (*aIter)->setMasterTextListStyle( mpMasterTextListStyle );
380 0 : (*aIter++)->addShape( rFilterBase, pTheme, rxShapes, aChildTransformation, getFillProperties(), NULL, pShapeMap );
381 0 : }
382 0 : }
383 :
384 0 : Reference< XShape > Shape::createAndInsert(
385 : ::oox::core::XmlFilterBase& rFilterBase,
386 : const OUString& rServiceName,
387 : const Theme* pTheme,
388 : const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
389 : const awt::Rectangle* /* pShapeRect */,
390 : bool bClearText,
391 : bool bDoNotInsertEmptyTextBody,
392 : basegfx::B2DHomMatrix& aParentTransformation,
393 : FillProperties& rShapeOrParentShapeFillProps )
394 : {
395 0 : bool bIsEmbMedia = false;
396 : SAL_INFO("oox.drawingml", OSL_THIS_FUNC << " id: " << msId);
397 :
398 0 : awt::Rectangle aShapeRectHmm( maPosition.X / 360, maPosition.Y / 360, maSize.Width / 360, maSize.Height / 360 );
399 :
400 0 : OUString aServiceName;
401 0 : if( rServiceName == "com.sun.star.drawing.GraphicObjectShape" &&
402 0 : mpGraphicPropertiesPtr && !mpGraphicPropertiesPtr->maAudio.msEmbed.isEmpty() )
403 : {
404 0 : aServiceName = finalizeServiceName( rFilterBase, "com.sun.star.presentation.MediaShape", aShapeRectHmm );
405 0 : bIsEmbMedia = true;
406 : }
407 : else
408 : {
409 0 : aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
410 : }
411 0 : sal_Bool bIsCustomShape = ( aServiceName == "com.sun.star.drawing.CustomShape" ||
412 0 : aServiceName == "com.sun.star.drawing.ConnectorShape" );
413 :
414 0 : basegfx::B2DHomMatrix aTransformation;
415 :
416 0 : if( maSize.Width != 1 || maSize.Height != 1)
417 : {
418 : // take care there are no zeros used by error
419 : aTransformation.scale(
420 : maSize.Width ? maSize.Width : 1.0,
421 0 : maSize.Height ? maSize.Height : 1.0 );
422 : }
423 :
424 0 : if( mbFlipH || mbFlipV || mnRotation != 0)
425 : {
426 : // calculate object's center
427 0 : basegfx::B2DPoint aCenter(0.5, 0.5);
428 0 : aCenter *= aTransformation;
429 :
430 : // center object at origin
431 0 : aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
432 :
433 0 : if( !bIsCustomShape && ( mbFlipH || mbFlipV ) )
434 : {
435 : // mirror around object's center
436 0 : aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 );
437 : }
438 :
439 0 : if( mnRotation != 0 )
440 : {
441 : // rotate around object's center
442 0 : aTransformation.rotate( F_PI180 * ( (double)mnRotation / 60000.0 ) );
443 : }
444 :
445 : // move object back from center
446 0 : aTransformation.translate( aCenter.getX(), aCenter.getY() );
447 : }
448 :
449 0 : if( maPosition.X != 0 || maPosition.Y != 0)
450 : {
451 : // if global position is used, add it to transformation
452 0 : aTransformation.translate( maPosition.X, maPosition.Y );
453 : }
454 :
455 0 : aTransformation = aParentTransformation*aTransformation;
456 0 : aParentTransformation = aTransformation;
457 0 : aTransformation.scale(1/360.0, 1/360.0);
458 :
459 : // special for lineshape
460 0 : if ( aServiceName == "com.sun.star.drawing.LineShape" )
461 : {
462 0 : ::basegfx::B2DPolygon aPoly;
463 0 : aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
464 0 : aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
465 0 : aPoly.transform( aTransformation );
466 :
467 : // now creating the corresponding PolyPolygon
468 0 : sal_Int32 i, nNumPoints = aPoly.count();
469 0 : uno::Sequence< awt::Point > aPointSequence( nNumPoints );
470 0 : awt::Point* pPoints = aPointSequence.getArray();
471 0 : for( i = 0; i < nNumPoints; ++i )
472 : {
473 0 : const ::basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) );
474 0 : pPoints[ i ] = awt::Point( static_cast< sal_Int32 >( aPoint.getX() ), static_cast< sal_Int32 >( aPoint.getY() ) );
475 0 : }
476 0 : uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 );
477 0 : aPolyPolySequence.getArray()[ 0 ] = aPointSequence;
478 :
479 0 : maShapeProperties.setProperty(PROP_PolyPolygon, aPolyPolySequence);
480 : }
481 0 : else if ( aServiceName == "com.sun.star.drawing.ConnectorShape" )
482 : {
483 0 : ::basegfx::B2DPolygon aPoly;
484 0 : aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
485 0 : aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
486 0 : aPoly.transform( aTransformation );
487 :
488 0 : basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );
489 0 : basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) );
490 0 : awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) );
491 0 : awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) );
492 :
493 0 : maShapeProperties.setProperty(PROP_StartPosition, aAWTStartPosition);
494 0 : maShapeProperties.setProperty(PROP_EndPosition, aAWTEndPosition);
495 : }
496 : else
497 : {
498 : // now set transformation for this object
499 0 : HomogenMatrix3 aMatrix;
500 :
501 :
502 0 : aMatrix.Line1.Column1 = aTransformation.get(0,0);
503 0 : aMatrix.Line1.Column2 = aTransformation.get(0,1);
504 0 : aMatrix.Line1.Column3 = aTransformation.get(0,2);
505 :
506 0 : aMatrix.Line2.Column1 = aTransformation.get(1,0);
507 0 : aMatrix.Line2.Column2 = aTransformation.get(1,1);
508 0 : aMatrix.Line2.Column3 = aTransformation.get(1,2);
509 :
510 0 : aMatrix.Line3.Column1 = aTransformation.get(2,0);
511 0 : aMatrix.Line3.Column2 = aTransformation.get(2,1);
512 0 : aMatrix.Line3.Column3 = aTransformation.get(2,2);
513 :
514 0 : maShapeProperties.setProperty(PROP_Transformation, aMatrix);
515 : }
516 :
517 0 : Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
518 0 : if ( !mxShape.is() )
519 0 : mxShape = Reference< drawing::XShape >( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW );
520 :
521 0 : Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
522 0 : if( mxShape.is() && xSet.is() )
523 : {
524 0 : if( !msName.isEmpty() )
525 : {
526 0 : Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );
527 0 : if( xNamed.is() )
528 0 : xNamed->setName( msName );
529 : }
530 0 : if (aServiceName != "com.sun.star.text.TextFrame")
531 0 : rxShapes->add( mxShape );
532 :
533 0 : if ( mbHidden || mbHiddenMasterShape )
534 : {
535 : SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "invisible shape with id: " << msId);
536 0 : const OUString sVisible( "Visible" );
537 0 : xSet->setPropertyValue( sVisible, Any( sal_False ) );
538 : }
539 :
540 0 : ActionLockGuard const alg(mxShape);
541 :
542 : // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
543 0 : if ( bClearText )
544 : {
545 0 : uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
546 0 : if ( xText.is() )
547 : {
548 0 : OUString aEmpty;
549 0 : xText->setString( aEmpty );
550 0 : }
551 : }
552 :
553 0 : const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
554 :
555 0 : LineProperties aLineProperties;
556 0 : aLineProperties.maLineFill.moFillType = XML_noFill;
557 0 : sal_Int32 nLinePhClr = -1;
558 0 : FillProperties aFillProperties;
559 0 : aFillProperties.moFillType = XML_noFill;
560 0 : sal_Int32 nFillPhClr = -1;
561 0 : EffectProperties aEffectProperties;
562 : // TODO: use ph color when applying effect properties
563 : //sal_Int32 nEffectPhClr = -1;
564 :
565 0 : if( pTheme )
566 : {
567 0 : if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
568 : {
569 0 : if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
570 0 : aLineProperties.assignUsed( *pLineProps );
571 0 : nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
572 :
573 : // Store style-related properties to InteropGrabBag to be able to export them back
574 0 : Sequence< PropertyValue > aProperties( 7 );
575 0 : PUT_PROP( aProperties, 0, "SchemeClr", pLineRef->maPhClr.getSchemeName() );
576 0 : PUT_PROP( aProperties, 1, "Idx", pLineRef->mnThemedIdx );
577 0 : PUT_PROP( aProperties, 2, "Color", nLinePhClr );
578 0 : PUT_PROP( aProperties, 3, "LineStyle", aLineProperties.getLineStyle() );
579 0 : PUT_PROP( aProperties, 4, "LineJoint", aLineProperties.getLineJoint() );
580 0 : PUT_PROP( aProperties, 5, "LineWidth", aLineProperties.getLineWidth() );
581 0 : PUT_PROP( aProperties, 6, "Transformations", pLineRef->maPhClr.getTransformations() );
582 0 : putPropertyToGrabBag( "StyleLnRef", Any( aProperties ) );
583 : }
584 0 : if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
585 : {
586 0 : if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) )
587 0 : aFillProperties.assignUsed( *pFillProps );
588 0 : nFillPhClr = pFillRef->maPhClr.getColor( rGraphicHelper );
589 :
590 0 : OUString sColorScheme = pFillRef->maPhClr.getSchemeName();
591 0 : if( !sColorScheme.isEmpty() )
592 : {
593 0 : Sequence< PropertyValue > aProperties(4);
594 0 : PUT_PROP( aProperties, 0, "SchemeClr", sColorScheme );
595 0 : PUT_PROP( aProperties, 1, "Idx", pFillRef->mnThemedIdx );
596 0 : PUT_PROP( aProperties, 2, "Color", nFillPhClr );
597 0 : PUT_PROP( aProperties, 3, "Transformations", pFillRef->maPhClr.getTransformations() );
598 :
599 0 : putPropertyToGrabBag( "StyleFillRef", Any( aProperties ) );
600 0 : }
601 : }
602 0 : if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_effectRef ) )
603 : {
604 0 : if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) )
605 0 : aEffectProperties.assignUsed( *pEffectProps );
606 : // TODO: use ph color when applying effect properties
607 : // nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
608 :
609 : // Store style-related properties to InteropGrabBag to be able to export them back
610 0 : Sequence< PropertyValue > aProperties( 3 );
611 0 : PUT_PROP( aProperties, 0, "SchemeClr", pEffectRef->maPhClr.getSchemeName() );
612 0 : PUT_PROP( aProperties, 1, "Idx", pEffectRef->mnThemedIdx );
613 0 : PUT_PROP( aProperties, 2, "Transformations", pEffectRef->maPhClr.getTransformations() );
614 0 : putPropertyToGrabBag( "StyleEffectRef", Any( aProperties ) );
615 : }
616 : }
617 :
618 0 : aLineProperties.assignUsed( getLineProperties() );
619 :
620 : // group fill inherits from parent
621 0 : if ( getFillProperties().moFillType.has() && getFillProperties().moFillType.get() == XML_grpFill )
622 0 : getFillProperties().assignUsed( rShapeOrParentShapeFillProps );
623 0 : aFillProperties.assignUsed( getFillProperties() );
624 0 : aEffectProperties.assignUsed ( getEffectProperties() );
625 :
626 0 : ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() );
627 :
628 : // add properties from textbody to shape properties
629 0 : if( mpTextBody.get() )
630 : {
631 0 : mpTextBody->getTextProperties().pushRotationAdjustments( mnRotation );
632 0 : aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap );
633 : // Push char properties as well - specifically useful when this is a placeholder
634 0 : if( mpMasterTextListStyle && mpMasterTextListStyle->getListStyle()[0]->getTextCharacterProperties().moHeight.has() )
635 0 : aShapeProps.setProperty(PROP_CharHeight, GetFontHeight( mpMasterTextListStyle->getListStyle()[0]->getTextCharacterProperties().moHeight.get() ));
636 : }
637 :
638 : // applying properties
639 0 : aShapeProps.assignUsed( getShapeProperties() );
640 0 : aShapeProps.assignUsed( maDefaultShapeProperties );
641 0 : if ( bIsEmbMedia || aServiceName == "com.sun.star.drawing.GraphicObjectShape" || aServiceName == "com.sun.star.drawing.OLE2Shape" )
642 0 : mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper );
643 0 : if ( mpTablePropertiesPtr.get() && aServiceName == "com.sun.star.drawing.TableShape" )
644 0 : mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle );
645 0 : aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr, mbFlipH, mbFlipV );
646 0 : aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr );
647 : // TODO: use ph color when applying effect properties
648 0 : aEffectProperties.pushToPropMap( aShapeProps, rGraphicHelper );
649 :
650 : // applying autogrowheight property before setting shape size, because
651 : // the shape size might be changed if currently autogrowheight is true
652 : // we must also check that the PropertySet supports the property.
653 0 : Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
654 0 : const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight );
655 0 : if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) )
656 0 : if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) )
657 0 : xSet->setPropertyValue( rPropName, Any( false ) );
658 :
659 : // do not set properties at a group shape (this causes
660 : // assertions from svx) ...
661 0 : if( aServiceName != "com.sun.star.drawing.GroupShape" )
662 : {
663 0 : if (aServiceName == "com.sun.star.text.TextFrame")
664 : {
665 0 : if (mpCustomShapePropertiesPtr && mpCustomShapePropertiesPtr->getShapeTypeOverride())
666 : {
667 0 : uno::Reference<beans::XPropertySet> propertySet (mxShape, uno::UNO_QUERY);
668 0 : uno::Sequence<beans::PropertyValue> aGrabBag;
669 0 : propertySet->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag;
670 0 : sal_Int32 length = aGrabBag.getLength();
671 0 : aGrabBag.realloc( length+1);
672 0 : aGrabBag[length].Name = "mso-orig-shape-type";
673 0 : aGrabBag[length].Value = uno::makeAny(mpCustomShapePropertiesPtr->getShapePresetTypeName());
674 0 : propertySet->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag));
675 : }
676 :
677 : // TextFrames have BackColor, not FillColor
678 0 : if (aShapeProps.hasProperty(PROP_FillColor))
679 : {
680 0 : aShapeProps.setProperty(PROP_BackColor, aShapeProps.getProperty(PROP_FillColor));
681 0 : aShapeProps.erase(PROP_FillColor);
682 : }
683 : // TextFrames have BackColorTransparency, not FillTransparence
684 0 : if (aShapeProps.hasProperty(PROP_FillTransparence))
685 : {
686 0 : aShapeProps.setProperty(PROP_BackColorTransparency, aShapeProps.getProperty(PROP_FillTransparence));
687 0 : aShapeProps.erase(PROP_FillTransparence);
688 : }
689 : // TextFrames have BackGrahicURL, not FillBitmapURL
690 0 : if (aShapeProps.hasProperty(PROP_FillBitmapURL))
691 : {
692 0 : aShapeProps.setProperty(PROP_BackGraphicURL, aShapeProps.getProperty(PROP_FillBitmapURL));
693 0 : aShapeProps.erase(PROP_FillBitmapURL);
694 : }
695 0 : if (aShapeProps.hasProperty(PROP_FillBitmapName))
696 : {
697 0 : uno::Any aAny = aShapeProps.getProperty(PROP_FillBitmapName);
698 0 : aShapeProps.setProperty(PROP_BackGraphicURL, rFilterBase.getModelObjectHelper().getFillBitmapUrl( aAny.get<OUString>() ));
699 : // aShapeProps.erase(PROP_FillBitmapName); // Maybe, leave the name as well
700 : }
701 : // And no LineColor property; individual borders can have colors
702 0 : if (aShapeProps.hasProperty(PROP_LineColor))
703 : {
704 0 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
705 : static const sal_Int32 aBorders[] =
706 : {
707 : PROP_TopBorder, PROP_LeftBorder, PROP_BottomBorder, PROP_RightBorder
708 : };
709 0 : for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
710 : {
711 0 : css::table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(PropertyMap::getPropertyName(aBorders[i])).get<css::table::BorderLine2>();
712 0 : aBorderLine.Color = aShapeProps.getProperty(PROP_LineColor).get<sal_Int32>();
713 0 : if (aLineProperties.moLineWidth.has())
714 0 : aBorderLine.LineWidth = convertEmuToHmm(aLineProperties.moLineWidth.get());
715 0 : aShapeProps.setProperty(aBorders[i], uno::makeAny(aBorderLine));
716 : }
717 0 : aShapeProps.erase(PROP_LineColor);
718 : }
719 0 : if(mnRotation)
720 : {
721 0 : uno::Reference<beans::XPropertySet> xPropertySet(mxShape, uno::UNO_QUERY);
722 0 : const OUString aGrabBagPropName = "FrameInteropGrabBag";
723 0 : uno::Sequence<beans::PropertyValue> aGrabBag;
724 0 : xPropertySet->getPropertyValue(aGrabBagPropName) >>= aGrabBag;
725 0 : beans::PropertyValue aPair;
726 0 : aPair.Name = "mso-rotation-angle";
727 0 : aPair.Value = uno::makeAny(mnRotation);
728 0 : if (aGrabBag.hasElements())
729 : {
730 0 : sal_Int32 nLength = aGrabBag.getLength();
731 0 : aGrabBag.realloc(nLength + 1);
732 0 : aGrabBag[nLength] = aPair;
733 : }
734 : else
735 : {
736 0 : aGrabBag.realloc(1);
737 0 : aGrabBag[0] = aPair;
738 : }
739 0 : xPropertySet->setPropertyValue(aGrabBagPropName, uno::makeAny(aGrabBag));
740 : }
741 : // TextFrames have ShadowFormat, not individual shadow properties.
742 0 : boost::optional<sal_Int32> oShadowDistance;
743 0 : if (aShapeProps.hasProperty(PROP_ShadowXDistance))
744 : {
745 0 : oShadowDistance = aShapeProps.getProperty(PROP_ShadowXDistance).get<sal_Int32>();
746 0 : aShapeProps.erase(PROP_ShadowXDistance);
747 : }
748 0 : if (aShapeProps.hasProperty(PROP_ShadowYDistance))
749 : {
750 : // There is a single 'dist' attribute, so no need to count the avg of x and y.
751 0 : aShapeProps.erase(PROP_ShadowYDistance);
752 : }
753 0 : boost::optional<sal_Int32> oShadowColor;
754 0 : if (aShapeProps.hasProperty(PROP_ShadowColor))
755 : {
756 0 : oShadowColor = aShapeProps.getProperty(PROP_ShadowColor).get<sal_Int32>();
757 0 : aShapeProps.erase(PROP_ShadowColor);
758 : }
759 0 : if (aShapeProps.hasProperty(PROP_Shadow))
760 0 : aShapeProps.erase(PROP_Shadow);
761 :
762 0 : if (oShadowDistance || oShadowColor || aEffectProperties.maShadow.moShadowDir.has())
763 : {
764 0 : css::table::ShadowFormat aFormat;
765 0 : if (oShadowColor)
766 0 : aFormat.Color = *oShadowColor;
767 0 : if (aEffectProperties.maShadow.moShadowDir.has())
768 : {
769 0 : css::table::ShadowLocation nLocation = css::table::ShadowLocation_NONE;
770 0 : switch (aEffectProperties.maShadow.moShadowDir.get())
771 : {
772 : case 13500000:
773 0 : nLocation = css::table::ShadowLocation_TOP_LEFT;
774 0 : break;
775 : case 18900000:
776 0 : nLocation = css::table::ShadowLocation_TOP_RIGHT;
777 0 : break;
778 : case 8100000:
779 0 : nLocation = css::table::ShadowLocation_BOTTOM_LEFT;
780 0 : break;
781 : case 2700000:
782 0 : nLocation = css::table::ShadowLocation_BOTTOM_RIGHT;
783 0 : break;
784 : }
785 0 : aFormat.Location = nLocation;
786 : }
787 0 : aFormat.ShadowWidth = *oShadowDistance;
788 0 : aShapeProps.setProperty(PROP_ShadowFormat, uno::makeAny(aFormat));
789 0 : }
790 : }
791 :
792 0 : PropertySet( xSet ).setProperties( aShapeProps );
793 0 : if (mbLockedCanvas)
794 : {
795 0 : putPropertyToGrabBag( "LockedCanvas", Any( true ) );
796 0 : if (aServiceName == "com.sun.star.drawing.LineShape")
797 : {
798 : // It seems the position and size for lines inside a locked canvas is absolute.
799 0 : mxShape->setPosition(awt::Point(aShapeRectHmm.X, aShapeRectHmm.Y));
800 0 : mxShape->setSize(awt::Size(aShapeRectHmm.Width, aShapeRectHmm.Height));
801 : }
802 : }
803 :
804 : // Store original fill and line colors of the shape and the theme color name to InteropGrabBag
805 0 : Sequence< PropertyValue > aProperties( 6 ); //allocate the maximum possible number of slots
806 0 : sal_Int32 nSize = 2;
807 0 : PUT_PROP( aProperties, 0, "OriginalSolidFillClr", aShapeProps.getProperty(PROP_FillColor) );
808 0 : PUT_PROP( aProperties, 1, "OriginalLnSolidFillClr", aShapeProps.getProperty(PROP_LineColor) );
809 0 : OUString sColorFillScheme = aFillProperties.maFillColor.getSchemeName();
810 0 : if( !aFillProperties.maFillColor.isPlaceHolder() && !sColorFillScheme.isEmpty() )
811 : {
812 0 : PUT_PROP( aProperties, nSize, "SpPrSolidFillSchemeClr", sColorFillScheme );
813 0 : nSize++;
814 0 : PUT_PROP( aProperties, nSize, "SpPrSolidFillSchemeClrTransformations",
815 : aFillProperties.maFillColor.getTransformations() );
816 0 : nSize++;
817 : }
818 0 : OUString sLnColorFillScheme = aLineProperties.maLineFill.maFillColor.getSchemeName();
819 0 : if( !aLineProperties.maLineFill.maFillColor.isPlaceHolder() && !sLnColorFillScheme.isEmpty() )
820 : {
821 0 : PUT_PROP( aProperties, nSize, "SpPrLnSolidFillSchemeClr", sLnColorFillScheme );
822 0 : nSize++;
823 0 : PUT_PROP( aProperties, nSize, "SpPrLnSolidFillSchemeClrTransformations",
824 : aLineProperties.maLineFill.maFillColor.getTransformations() );
825 0 : nSize++;
826 : }
827 0 : aProperties.realloc( nSize ); //shrink the Sequence if we didn't use all the slots
828 0 : putPropertiesToGrabBag( aProperties );
829 :
830 : // Store original gradient fill of the shape to InteropGrabBag
831 : // LibreOffice doesn't support all the kinds of gradient so we save its complete definition
832 0 : if( aShapeProps.hasProperty( PROP_FillGradient ) )
833 : {
834 0 : Sequence< PropertyValue > aGradientStops( aFillProperties.maGradientProps.maGradientStops.size() );
835 0 : ::std::map< double, Color >::iterator aIt = aFillProperties.maGradientProps.maGradientStops.begin();
836 0 : for( sal_uInt32 i = 0; i < aFillProperties.maGradientProps.maGradientStops.size(); ++i )
837 : { // for each stop in the gradient definition:
838 :
839 : // save position
840 0 : Sequence< PropertyValue > aGradientStop( 3 );
841 0 : PUT_PROP( aGradientStop, 0, "Pos", aIt->first );
842 :
843 0 : OUString sStopColorScheme = aIt->second.getSchemeName();
844 0 : if( sStopColorScheme.isEmpty() )
845 : {
846 : // save RGB color
847 0 : PUT_PROP( aGradientStop, 1, "RgbClr", aIt->second.getColor( rGraphicHelper, nFillPhClr ) );
848 : // in the case of a RGB color, transformations are already applied to
849 : // the color with the exception of alpha transformations. We only need
850 : // to keep the transparency value to calculate the alpha value later.
851 0 : if( aIt->second.hasTransparency() )
852 : {
853 0 : PUT_PROP( aGradientStop, 2, "Transparency", aIt->second.getTransparency() );
854 : }
855 : }
856 : else
857 : {
858 : // save color with scheme name
859 0 : PUT_PROP( aGradientStop, 1, "SchemeClr", sStopColorScheme );
860 : // save all color transformations
861 0 : PUT_PROP( aGradientStop, 2, "Transformations", aIt->second.getTransformations() );
862 : }
863 :
864 0 : PUT_PROP( aGradientStops, i, OUString::number( i ), aGradientStop );
865 0 : ++aIt;
866 0 : }
867 : // If getFillProperties.moFillType is unused that means gradient is defined by a theme
868 : // which is already saved into StyleFillRef property, so no need to save the explicit values too
869 0 : if( getFillProperties().moFillType.has() )
870 0 : putPropertyToGrabBag( "GradFillDefinition", Any( aGradientStops ) );
871 0 : putPropertyToGrabBag( "OriginalGradFill", aShapeProps.getProperty(PROP_FillGradient) );
872 0 : }
873 : }
874 :
875 : // These can have a custom geometry, so position should be set here,
876 : // after creation but before custom shape handling, using the position
877 : // we got from the caller.
878 0 : if (mbWps && aServiceName != "com.sun.star.text.TextFrame")
879 0 : mxShape->setPosition(maPosition);
880 :
881 0 : if( bIsCustomShape )
882 : {
883 0 : if ( mbFlipH )
884 0 : mpCustomShapePropertiesPtr->setMirroredX( true );
885 0 : if ( mbFlipV )
886 0 : mpCustomShapePropertiesPtr->setMirroredY( true );
887 0 : if( getTextBody() )
888 : {
889 0 : sal_Int32 nTextRotateAngle = static_cast< sal_Int32 >( getTextBody()->getTextProperties().moRotation.get( 0 ) );
890 0 : mpCustomShapePropertiesPtr->setTextRotateAngle( nTextRotateAngle / 60000 );
891 : }
892 :
893 : SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName << "'");
894 0 : mpCustomShapePropertiesPtr->pushToPropSet( rFilterBase, xSet, mxShape, maSize );
895 : }
896 0 : else if( getTextBody() )
897 0 : getTextBody()->getTextProperties().pushVertSimulation();
898 :
899 : // in some cases, we don't have any text body.
900 0 : if( getTextBody() && ( !bDoNotInsertEmptyTextBody || !mpTextBody->isEmpty() ) )
901 : {
902 0 : Reference < XText > xText( mxShape, UNO_QUERY );
903 0 : if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
904 : {
905 0 : TextCharacterProperties aCharStyleProperties;
906 0 : if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) )
907 : {
908 0 : if( pTheme )
909 0 : if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) )
910 0 : aCharStyleProperties.assignUsed( *pCharProps );
911 : SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "use font color");
912 0 : aCharStyleProperties.maCharColor.assignIfUsed( pFontRef->maPhClr );
913 : }
914 :
915 0 : Reference < XTextCursor > xAt = xText->createTextCursor();
916 0 : getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle );
917 0 : }
918 0 : }
919 : }
920 :
921 0 : if( mxShape.is() )
922 0 : finalizeXShape( rFilterBase, rxShapes );
923 :
924 0 : return mxShape;
925 : }
926 :
927 0 : void Shape::keepDiagramCompatibilityInfo( XmlFilterBase& rFilterBase )
928 : {
929 : try
930 : {
931 0 : if( !maDiagramDoms.hasElements() )
932 0 : return;
933 :
934 0 : Reference < XPropertySet > xSet( mxShape, UNO_QUERY_THROW );
935 0 : Reference < XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
936 0 : if ( !xSetInfo.is() )
937 0 : return;
938 :
939 0 : const OUString aGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
940 0 : if( !xSetInfo->hasPropertyByName( aGrabBagPropName ) )
941 0 : return;
942 :
943 0 : Sequence < PropertyValue > aGrabBag;
944 0 : xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
945 :
946 : // We keep the previous items, if present
947 0 : if ( aGrabBag.hasElements() )
948 : {
949 0 : sal_Int32 length = aGrabBag.getLength();
950 0 : aGrabBag.realloc( length+maDiagramDoms.getLength() );
951 :
952 0 : for( sal_Int32 i = 0; i < maDiagramDoms.getLength(); ++i )
953 0 : aGrabBag[length+i] = maDiagramDoms[i];
954 :
955 0 : xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
956 : } else
957 0 : xSet->setPropertyValue( aGrabBagPropName, Any( maDiagramDoms ) );
958 :
959 0 : xSet->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True ) );
960 0 : xSet->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True ) );
961 :
962 : // Replace existing shapes with a new Graphic Object rendered
963 : // from them
964 0 : Reference < XShape > xShape( renderDiagramToGraphic( rFilterBase ) );
965 0 : Reference < XShapes > xShapes( mxShape, UNO_QUERY_THROW );
966 0 : while( xShapes->hasElements() )
967 0 : xShapes->remove( Reference < XShape > ( xShapes->getByIndex( 0 ), UNO_QUERY_THROW ) );
968 0 : xShapes->add( xShape );
969 : }
970 0 : catch( const Exception& e )
971 : {
972 : SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message );
973 : }
974 : }
975 :
976 0 : Reference < XShape > Shape::renderDiagramToGraphic( XmlFilterBase& rFilterBase )
977 : {
978 0 : Reference< XShape > xShape;
979 :
980 : try
981 : {
982 0 : if( !maDiagramDoms.hasElements() )
983 0 : return xShape;
984 :
985 : // Stream in which to place the rendered shape
986 0 : SvMemoryStream mpTempStream;
987 0 : Reference < io::XStream > xStream( new utl::OStreamWrapper( mpTempStream ) );
988 0 : Reference < io::XOutputStream > xOutputStream( xStream->getOutputStream() );
989 :
990 : // Rendering format
991 0 : OUString sFormat( "PNG" );
992 :
993 : // Size of the rendering
994 0 : awt::Size aActualSize = mxShape->getSize();
995 0 : Size aResolution( Application::GetDefaultDevice()->LogicToPixel( Size( 100, 100 ), MAP_CM ) );
996 0 : double fPixelsPer100thmm = static_cast < double > ( aResolution.Width() ) / 100000.0;
997 0 : awt::Size aSize = awt::Size( static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Width ) + 0.5 ),
998 0 : static_cast < sal_Int32 > ( ( fPixelsPer100thmm * aActualSize.Height ) + 0.5 ) );
999 :
1000 0 : Sequence< PropertyValue > aFilterData( 7 );
1001 0 : aFilterData[ 0 ].Name = "Compression";
1002 0 : aFilterData[ 0 ].Value <<= static_cast < sal_Int32 > ( 9 );
1003 0 : aFilterData[ 1 ].Name = "Interlaced";
1004 0 : aFilterData[ 1 ].Value <<= static_cast < sal_Int32 > ( 1 );
1005 0 : aFilterData[ 2 ].Name = "Translucent";
1006 0 : aFilterData[ 2 ].Value <<= static_cast < sal_Int32 > ( 1 );
1007 0 : aFilterData[ 3 ].Name = "PixelWidth";
1008 0 : aFilterData[ 3 ].Value <<= aSize.Width;
1009 0 : aFilterData[ 4 ].Name = "PixelHeight";
1010 0 : aFilterData[ 4 ].Value <<= aSize.Height;
1011 0 : aFilterData[ 5 ].Name = "LogicalWidth";
1012 0 : aFilterData[ 5 ].Value <<= aActualSize.Width;
1013 0 : aFilterData[ 6 ].Name = "LogicalHeight";
1014 0 : aFilterData[ 6 ].Value <<= aActualSize.Height;
1015 :
1016 0 : Sequence < PropertyValue > aDescriptor( 3 );
1017 0 : aDescriptor[ 0 ].Name = "OutputStream";
1018 0 : aDescriptor[ 0 ].Value <<= xOutputStream;
1019 0 : aDescriptor[ 1 ].Name = "FilterName";
1020 0 : aDescriptor[ 1 ].Value <<= sFormat;
1021 0 : aDescriptor[ 2 ].Name = "FilterData";
1022 0 : aDescriptor[ 2 ].Value <<= aFilterData;
1023 :
1024 0 : Reference < lang::XComponent > xSourceDoc( mxShape, UNO_QUERY_THROW );
1025 0 : Reference < XGraphicExportFilter > xGraphicExporter = GraphicExportFilter::create( rFilterBase.getComponentContext() );
1026 0 : xGraphicExporter->setSourceDocument( xSourceDoc );
1027 0 : xGraphicExporter->filter( aDescriptor );
1028 :
1029 0 : mpTempStream.Seek( STREAM_SEEK_TO_BEGIN );
1030 :
1031 0 : Graphic aGraphic;
1032 0 : GraphicFilter aFilter( false );
1033 0 : if ( aFilter.ImportGraphic( aGraphic, "", mpTempStream, GRFILTER_FORMAT_NOTFOUND, NULL, 0, static_cast < Sequence < PropertyValue >* > ( NULL ), NULL ) != GRFILTER_OK )
1034 : {
1035 : SAL_WARN( "oox.drawingml", OSL_THIS_FUNC
1036 : << "Unable to import rendered stream into graphic object" );
1037 0 : return xShape;
1038 : }
1039 :
1040 0 : Reference < graphic::XGraphic > xGraphic( aGraphic.GetXGraphic() );
1041 0 : Reference < lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
1042 0 : xShape = Reference < XShape > ( xServiceFact->createInstance( OUString( "com.sun.star.drawing.GraphicObjectShape" ) ), UNO_QUERY_THROW );
1043 0 : Reference < XPropertySet > xPropSet( xShape, UNO_QUERY_THROW );
1044 0 : xPropSet->setPropertyValue( OUString( "Graphic" ), Any( xGraphic ) );
1045 0 : xPropSet->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True ) );
1046 0 : xPropSet->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True ) );
1047 0 : xPropSet->setPropertyValue( OUString( "Name" ), Any( OUString( "RenderedShapes" ) ) );
1048 : }
1049 0 : catch( const Exception& e )
1050 : {
1051 : SAL_WARN( "oox.drawingml", OSL_THIS_FUNC << "Exception: " << e.Message );
1052 : }
1053 :
1054 0 : return xShape;
1055 : }
1056 :
1057 0 : void Shape::setTextBody(const TextBodyPtr & pTextBody)
1058 : {
1059 0 : mpTextBody = pTextBody;
1060 0 : }
1061 :
1062 :
1063 0 : TextBodyPtr Shape::getTextBody()
1064 : {
1065 0 : return mpTextBody;
1066 : }
1067 :
1068 0 : void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
1069 : {
1070 : SAL_INFO("oox.drawingml", OSL_THIS_FUNC << "set master text list style to shape id: " << msId);
1071 :
1072 0 : mpMasterTextListStyle = pMasterTextListStyle;
1073 0 : }
1074 :
1075 0 : OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const awt::Rectangle& rShapeRect )
1076 : {
1077 0 : OUString aServiceName = rServiceName;
1078 0 : switch( meFrameType )
1079 : {
1080 : case FRAMETYPE_OLEOBJECT:
1081 : {
1082 0 : awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height );
1083 0 : if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) )
1084 0 : aServiceName = "com.sun.star.drawing.OLE2Shape";
1085 :
1086 : // get the path to the representation graphic
1087 0 : OUString aGraphicPath;
1088 0 : if( !mxOleObjectInfo->maShapeId.isEmpty() )
1089 0 : if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() )
1090 0 : if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) )
1091 0 : aGraphicPath = pVmlShape->getGraphicPath();
1092 :
1093 : // import and store the graphic
1094 0 : if( !aGraphicPath.isEmpty() )
1095 : {
1096 0 : Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
1097 0 : if( xGraphic.is() )
1098 0 : maShapeProperties.setProperty(PROP_Graphic, xGraphic);
1099 0 : }
1100 : }
1101 0 : break;
1102 :
1103 : default:;
1104 : }
1105 0 : return aServiceName;
1106 : }
1107 :
1108 0 : void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
1109 : {
1110 0 : switch( meFrameType )
1111 : {
1112 : case FRAMETYPE_CHART:
1113 : {
1114 : OSL_ENSURE( !mxChartShapeInfo->maFragmentPath.isEmpty(), "Shape::finalizeXShape - missing chart fragment" );
1115 0 : if( mxShape.is() && !mxChartShapeInfo->maFragmentPath.isEmpty() ) try
1116 : {
1117 : // set the chart2 OLE class ID at the OLE shape
1118 0 : PropertySet aShapeProp( mxShape );
1119 0 : aShapeProp.setProperty( PROP_CLSID, OUString( "12dcae26-281f-416f-a234-c3086127382e" ) );
1120 :
1121 : // get the XModel interface of the embedded object from the OLE shape
1122 0 : Reference< frame::XModel > xDocModel;
1123 0 : aShapeProp.getProperty( xDocModel, PROP_Model );
1124 0 : Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
1125 :
1126 : // load the chart data from the XML fragment
1127 0 : chart::ChartSpaceModel aModel;
1128 0 : rFilter.importFragment( new chart::ChartSpaceFragment( rFilter, mxChartShapeInfo->maFragmentPath, aModel ) );
1129 :
1130 : // convert imported chart model to chart document
1131 0 : Reference< drawing::XShapes > xExternalPage;
1132 0 : if( !mxChartShapeInfo->mbEmbedShapes )
1133 0 : xExternalPage = rxShapes;
1134 0 : if( rFilter.getChartConverter() )
1135 : {
1136 0 : rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
1137 0 : if( !xChartDoc->hasInternalDataProvider() )
1138 : {
1139 0 : Reference< chart2::data::XDataReceiver > xDataRec( xChartDoc, UNO_QUERY );
1140 0 : Reference< chart2::data::XDataSource > xData( xDataRec->getUsedData(), UNO_QUERY );
1141 0 : if( xData->getDataSequences().getLength() <= 0 || xData->getDataSequences()[0]->getValues()->getData().getLength() <= 0 )
1142 : {
1143 0 : rFilter.useInternalChartDataTable( true );
1144 0 : rFilter.getChartConverter()->convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
1145 0 : rFilter.useInternalChartDataTable( false );
1146 0 : }
1147 : }
1148 :
1149 0 : }
1150 : }
1151 0 : catch( Exception& )
1152 : {
1153 : }
1154 : }
1155 0 : break;
1156 :
1157 : default:;
1158 : }
1159 0 : }
1160 :
1161 0 : void Shape::putPropertyToGrabBag( const OUString& sPropertyName, const Any& aPropertyValue )
1162 : {
1163 0 : PropertyValue pNewProperty;
1164 0 : pNewProperty.Name = sPropertyName;
1165 0 : pNewProperty.Value = aPropertyValue;
1166 0 : putPropertyToGrabBag( pNewProperty );
1167 0 : }
1168 :
1169 0 : void Shape::putPropertyToGrabBag( const PropertyValue& pProperty )
1170 : {
1171 0 : Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1172 0 : Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1173 0 : const OUString& aGrabBagPropName = OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG );
1174 0 : if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1175 : {
1176 0 : Sequence< PropertyValue > aGrabBag;
1177 0 : xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1178 :
1179 0 : sal_Int32 length = aGrabBag.getLength();
1180 0 : aGrabBag.realloc( length + 1 );
1181 0 : aGrabBag[length] = pProperty;
1182 :
1183 0 : xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
1184 0 : }
1185 0 : }
1186 :
1187 0 : void Shape::putPropertiesToGrabBag( const Sequence< PropertyValue >& aProperties )
1188 : {
1189 0 : Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
1190 0 : Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
1191 0 : const OUString& aGrabBagPropName = OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG );
1192 0 : if( mxShape.is() && xSet.is() && xSetInfo.is() && xSetInfo->hasPropertyByName( aGrabBagPropName ) )
1193 : {
1194 : // get existing grab bag
1195 0 : Sequence< PropertyValue > aGrabBag;
1196 0 : xSet->getPropertyValue( aGrabBagPropName ) >>= aGrabBag;
1197 0 : sal_Int32 length = aGrabBag.getLength();
1198 :
1199 : // update grab bag size to contain the new items
1200 0 : aGrabBag.realloc( length + aProperties.getLength() );
1201 :
1202 : // put the new items
1203 0 : for( sal_Int32 i=0; i < aProperties.getLength(); ++i )
1204 : {
1205 0 : aGrabBag[length + i].Name = aProperties[i].Name;
1206 0 : aGrabBag[length + i].Value = aProperties[i].Value;
1207 : }
1208 :
1209 : // put it back to the shape
1210 0 : xSet->setPropertyValue( aGrabBagPropName, Any( aGrabBag ) );
1211 0 : }
1212 0 : }
1213 :
1214 0 : uno::Sequence< uno::Sequence< uno::Any > > Shape::resolveRelationshipsOfTypeFromOfficeDoc(core::XmlFilterBase& rFilter, const OUString& sFragment, const OUString& sType )
1215 : {
1216 0 : uno::Sequence< uno::Sequence< uno::Any > > xRelListTemp;
1217 0 : sal_Int32 counter = 0;
1218 :
1219 0 : core::RelationsRef xRels = rFilter.importRelations( sFragment );
1220 0 : if ( xRels )
1221 : {
1222 0 : core::RelationsRef xImageRels = xRels->getRelationsFromTypeFromOfficeDoc( sType );
1223 0 : if ( xImageRels )
1224 : {
1225 0 : xRelListTemp.realloc( xImageRels->size() );
1226 0 : for( ::std::map< OUString, core::Relation >::const_iterator aIt = xImageRels->begin(), aEnd = xImageRels->end(); aIt != aEnd; ++aIt )
1227 : {
1228 0 : uno::Sequence< uno::Any > diagramRelTuple (3);
1229 : // [0] => RID, [1] => InputStream [2] => extension
1230 0 : OUString sRelId = aIt->second.maId;
1231 :
1232 0 : diagramRelTuple[0] = uno::makeAny ( sRelId );
1233 0 : OUString sTarget = xImageRels->getFragmentPathFromRelId( sRelId );
1234 :
1235 0 : uno::Reference< io::XInputStream > xImageInputStrm( rFilter.openInputStream( sTarget ), uno::UNO_SET_THROW );
1236 0 : StreamDataSequence dataSeq;
1237 0 : if ( rFilter.importBinaryData( dataSeq, sTarget ) )
1238 : {
1239 0 : diagramRelTuple[1] = uno::makeAny( dataSeq );
1240 : }
1241 :
1242 0 : diagramRelTuple[2] = uno::makeAny( sTarget.copy( sTarget.lastIndexOf(".") ) );
1243 :
1244 0 : xRelListTemp[counter] = diagramRelTuple;
1245 0 : ++counter;
1246 0 : }
1247 0 : xRelListTemp.realloc(counter);
1248 :
1249 0 : }
1250 : }
1251 0 : return xRelListTemp;
1252 : }
1253 :
1254 0 : } }
1255 :
1256 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|