1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/drawingml/shape.hxx"
21 #include "drawingml/customshapeproperties.hxx"
22 #include "oox/drawingml/theme.hxx"
23 #include "oox/drawingml/fillproperties.hxx"
24 #include "drawingml/graphicproperties.hxx"
25 #include <drawingml/scene3dcontext.hxx>
26 #include "oox/drawingml/lineproperties.hxx"
27 #include "effectproperties.hxx"
28 #include "oox/drawingml/shapepropertymap.hxx"
29 #include "drawingml/textbody.hxx"
30 #include <drawingml/ThemeOverrideFragmentHandler.hxx>
31 #include "drawingml/table/tableproperties.hxx"
32 #include "oox/drawingml/chart/chartconverter.hxx"
33 #include "drawingml/chart/chartspacefragment.hxx"
34 #include "drawingml/chart/chartspacemodel.hxx"
35 #include "oox/ppt/pptimport.hxx"
36 #include "oox/vml/vmldrawing.hxx"
37 #include "oox/vml/vmlshape.hxx"
38 #include "oox/vml/vmlshapecontainer.hxx"
39 #include "oox/core/xmlfilterbase.hxx"
40 #include "oox/helper/graphichelper.hxx"
41 #include "oox/helper/propertyset.hxx"
42 #include "oox/helper/modelobjecthelper.hxx"
44 #include <tools/gen.hxx>
45 #include <tools/mapunit.hxx>
46 #include <editeng/unoprnms.hxx>
47 #include <com/sun/star/awt/Size.hpp>
48 #include <com/sun/star/graphic/XGraphic.hpp>
49 #include <com/sun/star/container/XNamed.hpp>
50 #include <com/sun/star/container/XNameContainer.hpp>
51 #include <com/sun/star/beans/XMultiPropertySet.hpp>
52 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 #include <com/sun/star/xml/AttributeData.hpp>
54 #include <com/sun/star/xml/sax/XFastSAXSerializable.hpp>
55 #include <com/sun/star/drawing/HomogenMatrix3.hpp>
56 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
57 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
58 #include <com/sun/star/text/XText.hpp>
59 #include <com/sun/star/table/BorderLine2.hpp>
60 #include <com/sun/star/table/ShadowFormat.hpp>
61 #include <com/sun/star/chart2/XChartDocument.hpp>
62 #include <com/sun/star/style/ParagraphAdjust.hpp>
63 #include <com/sun/star/io/XOutputStream.hpp>
65 #include <basegfx/point/b2dpoint.hxx>
66 #include <basegfx/polygon/b2dpolygon.hxx>
67 #include <basegfx/matrix/b2dhommatrix.hxx>
68 #include <com/sun/star/document/XActionLockable.hpp>
69 #include <com/sun/star/chart2/data/XDataReceiver.hpp>
70 #include <svl/outstrm.hxx>
71 #include <svx/svdtrans.hxx>
72 #include <unotools/streamwrap.hxx>
73 #include <unotools/fltrcfg.hxx>
74 #include <vcl/graph.hxx>
75 #include <vcl/graphicfilter.hxx>
76 #include <vcl/svapp.hxx>
78 #include <vcl/wmf.hxx>
80 using namespace ::oox::core
;
81 using namespace ::com::sun::star
;
82 using namespace ::com::sun::star::uno
;
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::frame
;
85 using namespace ::com::sun::star::text
;
86 using namespace ::com::sun::star::drawing
;
87 using namespace ::com::sun::star::style
;
89 namespace oox
{ namespace drawingml
{
91 #define PUT_PROP( aProperties, nPos, sPropName, aPropValue ) \
92 aProperties[nPos].Name = sPropName; \
93 aProperties[nPos].Value = Any( aPropValue );
95 Shape::Shape( const sal_Char
* pServiceName
, bool bDefaultHeight
)
97 , mpLinePropertiesPtr( new LineProperties
)
98 , mpShapeRefLinePropPtr( new LineProperties
)
99 , mpFillPropertiesPtr( new FillProperties
)
100 , mpShapeRefFillPropPtr( new FillProperties
)
101 , mpGraphicPropertiesPtr( new GraphicProperties
)
102 , mpCustomShapePropertiesPtr( new CustomShapeProperties
)
103 , mp3DPropertiesPtr( new Shape3DProperties
)
104 , mpEffectPropertiesPtr( new EffectProperties
)
105 , mpShapeRefEffectPropPtr( new EffectProperties
)
106 , mpMasterTextListStyle( new TextListStyle
)
108 , meFrameType( FRAMETYPE_GENERIC
)
113 , mbHiddenMasterShape( false )
114 , mbLockedCanvas( false )
117 , mbHasLinkedTxbx( false )
121 msServiceName
= OUString::createFromAscii( pServiceName
);
122 setDefaults(bDefaultHeight
);
125 Shape::Shape( const ShapePtr
& pSourceShape
)
127 , mbIsChild( pSourceShape
->mbIsChild
)
128 , mpTextBody(pSourceShape
->mpTextBody
)
129 , mpLinePropertiesPtr( pSourceShape
->mpLinePropertiesPtr
)
130 , mpShapeRefLinePropPtr( pSourceShape
->mpShapeRefLinePropPtr
)
131 , mpFillPropertiesPtr( pSourceShape
->mpFillPropertiesPtr
)
132 , mpShapeRefFillPropPtr( pSourceShape
->mpShapeRefFillPropPtr
)
133 , mpGraphicPropertiesPtr( pSourceShape
->mpGraphicPropertiesPtr
)
134 , mpCustomShapePropertiesPtr( pSourceShape
->mpCustomShapePropertiesPtr
)
135 , mpTablePropertiesPtr( pSourceShape
->mpTablePropertiesPtr
)
136 , mp3DPropertiesPtr( pSourceShape
->mp3DPropertiesPtr
)
137 , mpEffectPropertiesPtr (pSourceShape
->mpEffectPropertiesPtr
)
138 , mpShapeRefEffectPropPtr(pSourceShape
->mpShapeRefEffectPropPtr
)
139 , maShapeProperties( pSourceShape
->maShapeProperties
)
140 , mpMasterTextListStyle( pSourceShape
->mpMasterTextListStyle
)
142 , msServiceName( pSourceShape
->msServiceName
)
143 , msName( pSourceShape
->msName
)
144 , msId( pSourceShape
->msId
)
145 , mnSubType( pSourceShape
->mnSubType
)
146 , moSubTypeIndex( pSourceShape
->moSubTypeIndex
)
147 , maShapeStyleRefs( pSourceShape
->maShapeStyleRefs
)
148 , maSize( pSourceShape
->maSize
)
149 , maPosition( pSourceShape
->maPosition
)
150 , meFrameType( pSourceShape
->meFrameType
)
151 , mnRotation( pSourceShape
->mnRotation
)
152 , mbFlipH( pSourceShape
->mbFlipH
)
153 , mbFlipV( pSourceShape
->mbFlipV
)
154 , mbHidden( pSourceShape
->mbHidden
)
155 , mbHiddenMasterShape( pSourceShape
->mbHiddenMasterShape
)
156 , mbLockedCanvas( pSourceShape
->mbLockedCanvas
)
157 , mbWps( pSourceShape
->mbWps
)
158 , mbTextBox( pSourceShape
->mbTextBox
)
160 , mbHasLinkedTxbx(false)
161 , maDiagramDoms( pSourceShape
->maDiagramDoms
)
168 table::TablePropertiesPtr
Shape::getTableProperties()
170 if ( !mpTablePropertiesPtr
.get() )
171 mpTablePropertiesPtr
.reset( new table::TableProperties() );
172 return mpTablePropertiesPtr
;
175 void Shape::setDefaults(bool bHeight
)
177 maDefaultShapeProperties
.setProperty(PROP_TextAutoGrowHeight
, false);
178 maDefaultShapeProperties
.setProperty(PROP_TextWordWrap
, true);
179 maDefaultShapeProperties
.setProperty(PROP_TextLeftDistance
, static_cast< sal_Int32
>( 250 ));
180 maDefaultShapeProperties
.setProperty(PROP_TextUpperDistance
, static_cast< sal_Int32
>( 125 ));
181 maDefaultShapeProperties
.setProperty(PROP_TextRightDistance
, static_cast< sal_Int32
>( 250 ));
182 maDefaultShapeProperties
.setProperty(PROP_TextLowerDistance
, static_cast< sal_Int32
>( 125 ));
184 maDefaultShapeProperties
.setProperty(PROP_CharHeight
, static_cast< float >( 18.0 ));
185 maDefaultShapeProperties
.setProperty(PROP_TextVerticalAdjust
, TextVerticalAdjust_TOP
);
186 maDefaultShapeProperties
.setProperty(PROP_ParaAdjust
, static_cast< sal_Int16
>( ParagraphAdjust_LEFT
)); // check for RTL?
189 ::oox::vml::OleObjectInfo
& Shape::setOleObjectType()
191 OSL_ENSURE( meFrameType
== FRAMETYPE_GENERIC
, "Shape::setOleObjectType - multiple frame types" );
192 meFrameType
= FRAMETYPE_OLEOBJECT
;
193 mxOleObjectInfo
.reset( new ::oox::vml::OleObjectInfo( true ) );
194 return *mxOleObjectInfo
;
197 ChartShapeInfo
& Shape::setChartType( bool bEmbedShapes
)
199 OSL_ENSURE( meFrameType
== FRAMETYPE_GENERIC
, "Shape::setChartType - multiple frame types" );
200 meFrameType
= FRAMETYPE_CHART
;
201 msServiceName
= "com.sun.star.drawing.OLE2Shape";
202 mxChartShapeInfo
.reset( new ChartShapeInfo( bEmbedShapes
) );
203 return *mxChartShapeInfo
;
206 void Shape::setDiagramType()
208 OSL_ENSURE( meFrameType
== FRAMETYPE_GENERIC
, "Shape::setDiagramType - multiple frame types" );
209 meFrameType
= FRAMETYPE_DIAGRAM
;
210 msServiceName
= "com.sun.star.drawing.GroupShape";
214 void Shape::setTableType()
216 OSL_ENSURE( meFrameType
== FRAMETYPE_GENERIC
, "Shape::setTableType - multiple frame types" );
217 meFrameType
= FRAMETYPE_TABLE
;
218 msServiceName
= "com.sun.star.drawing.TableShape";
222 void Shape::setServiceName( const sal_Char
* pServiceName
)
225 msServiceName
= OUString::createFromAscii( pServiceName
);
228 const ShapeStyleRef
* Shape::getShapeStyleRef( sal_Int32 nRefType
) const
230 ShapeStyleRefMap::const_iterator aIt
= maShapeStyleRefs
.find( nRefType
);
231 return (aIt
== maShapeStyleRefs
.end()) ? 0 : &aIt
->second
;
234 void Shape::addShape(
235 ::oox::core::XmlFilterBase
& rFilterBase
,
237 const Reference
< XShapes
>& rxShapes
,
238 const basegfx::B2DHomMatrix
& aTransformation
,
239 FillProperties
& rShapeOrParentShapeFillProps
,
240 const awt::Rectangle
* pShapeRect
,
241 ShapeIdMap
* pShapeMap
)
243 SAL_INFO("oox.drawingml", OSL_THIS_FUNC
<< " id: " << msId
);
247 OUString
sServiceName( msServiceName
);
248 if( !sServiceName
.isEmpty() )
250 basegfx::B2DHomMatrix
aMatrix( aTransformation
);
251 Reference
< XShape
> xShape( createAndInsert( rFilterBase
, sServiceName
, pTheme
, rxShapes
, pShapeRect
, false, false, aMatrix
, rShapeOrParentShapeFillProps
) );
253 if( pShapeMap
&& !msId
.isEmpty() )
255 (*pShapeMap
)[ msId
] = shared_from_this();
258 // if this is a group shape, we have to add also each child shape
259 Reference
< XShapes
> xShapes( xShape
, UNO_QUERY
);
261 addChildren( rFilterBase
, *this, pTheme
, xShapes
, pShapeRect
? *pShapeRect
: awt::Rectangle( maPosition
.X
, maPosition
.Y
, maSize
.Width
, maSize
.Height
), pShapeMap
, aMatrix
);
263 if( meFrameType
== FRAMETYPE_DIAGRAM
)
265 if( !SvtFilterOptions::Get().IsSmartArt2Shape() )
266 keepDiagramCompatibilityInfo( rFilterBase
);
270 catch( const Exception
& e
)
272 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC
<< "Exception: " << e
.Message
);
276 void Shape::setLockedCanvas(bool bLockedCanvas
)
278 mbLockedCanvas
= bLockedCanvas
;
281 void Shape::setWps(bool bWps
)
286 void Shape::setTextBox(bool bTextBox
)
288 mbTextBox
= bTextBox
;
291 void Shape::applyShapeReference( const Shape
& rReferencedShape
, bool bUseText
)
293 SAL_INFO("oox", OSL_THIS_FUNC
<< "apply shape reference: " << rReferencedShape
.msId
<< " to shape id: " << msId
);
295 if ( rReferencedShape
.mpTextBody
.get() && bUseText
)
296 mpTextBody
= TextBodyPtr( new TextBody( *rReferencedShape
.mpTextBody
.get() ) );
299 maShapeProperties
= rReferencedShape
.maShapeProperties
;
300 mpShapeRefLinePropPtr
= LinePropertiesPtr( new LineProperties( *rReferencedShape
.mpLinePropertiesPtr
.get() ) );
301 mpShapeRefFillPropPtr
= FillPropertiesPtr( new FillProperties( *rReferencedShape
.mpFillPropertiesPtr
.get() ) );
302 mpCustomShapePropertiesPtr
= CustomShapePropertiesPtr( new CustomShapeProperties( *rReferencedShape
.mpCustomShapePropertiesPtr
.get() ) );
303 mpTablePropertiesPtr
= table::TablePropertiesPtr( rReferencedShape
.mpTablePropertiesPtr
.get() ? new table::TableProperties( *rReferencedShape
.mpTablePropertiesPtr
.get() ) : NULL
);
304 mpShapeRefEffectPropPtr
= EffectPropertiesPtr( new EffectProperties( *rReferencedShape
.mpEffectPropertiesPtr
.get() ) );
305 mpMasterTextListStyle
= TextListStylePtr( new TextListStyle( *rReferencedShape
.mpMasterTextListStyle
.get() ) );
306 maShapeStyleRefs
= rReferencedShape
.maShapeStyleRefs
;
307 maSize
= rReferencedShape
.maSize
;
308 maPosition
= rReferencedShape
.maPosition
;
309 mnRotation
= rReferencedShape
.mnRotation
;
310 mbFlipH
= rReferencedShape
.mbFlipH
;
311 mbFlipV
= rReferencedShape
.mbFlipV
;
312 mbHidden
= rReferencedShape
.mbHidden
;
315 void Shape::addChildren( ::oox::core::XmlFilterBase
& rFilterBase
,
317 const Reference
< XShapes
>& rxShapes
,
318 basegfx::B2DHomMatrix
& aTransformation
,
319 const awt::Rectangle
* pShapeRect
,
320 ShapeIdMap
* pShapeMap
)
322 addChildren(rFilterBase
, *this, pTheme
, rxShapes
,
325 awt::Rectangle( maPosition
.X
, maPosition
.Y
, maSize
.Width
, maSize
.Height
),
326 pShapeMap
, aTransformation
);
329 struct ActionLockGuard
331 explicit ActionLockGuard(Reference
<drawing::XShape
> const& xShape
)
332 : m_xLockable(xShape
, UNO_QUERY
)
334 if (m_xLockable
.is()) {
335 m_xLockable
->addActionLock();
340 if (m_xLockable
.is()) {
341 m_xLockable
->removeActionLock();
345 Reference
<document::XActionLockable
> m_xLockable
;
348 // for group shapes, the following method is also adding each child
349 void Shape::addChildren(
350 XmlFilterBase
& rFilterBase
,
353 const Reference
< XShapes
>& rxShapes
,
354 const awt::Rectangle
&,
355 ShapeIdMap
* pShapeMap
,
356 const basegfx::B2DHomMatrix
& aTransformation
)
358 basegfx::B2DHomMatrix aChildTransformation
;
360 aChildTransformation
.translate(-maChPosition
.X
, -maChPosition
.Y
);
361 aChildTransformation
.scale(1/(maChSize
.Width
? maChSize
.Width
: 1.0), 1/(maChSize
.Height
? maChSize
.Height
: 1.0));
363 // Child position and size is typically non-zero, but it's allowed to have
364 // it like that, and in that case Word ignores the parent transformation
365 // (excluding translate component).
366 if (!mbWps
|| maChPosition
.X
|| maChPosition
.Y
|| maChSize
.Width
|| maChSize
.Height
)
368 aChildTransformation
*= aTransformation
;
372 basegfx::B2DVector aScale
, aTranslate
;
373 double fRotate
, fShearX
;
374 aTransformation
.decompose(aScale
, aTranslate
, fRotate
, fShearX
);
375 aChildTransformation
.translate(aTranslate
.getX(), aTranslate
.getY());
378 SAL_INFO("oox.drawingml", OSL_THIS_FUNC
<< "parent matrix:\n"
379 << aChildTransformation
.get(0, 0) << " "
380 << aChildTransformation
.get(0, 1) << " "
381 << aChildTransformation
.get(0, 2) << "\n"
382 << aChildTransformation
.get(1, 0) << " "
383 << aChildTransformation
.get(1, 1) << " "
384 << aChildTransformation
.get(1, 2) << "\n"
385 << aChildTransformation
.get(2, 0) << " "
386 << aChildTransformation
.get(2, 1) << " "
387 << aChildTransformation
.get(2, 2));
389 std::vector
< ShapePtr
>::iterator
aIter( rMaster
.maChildren
.begin() );
390 while( aIter
!= rMaster
.maChildren
.end() ) {
391 (*aIter
)->setMasterTextListStyle( mpMasterTextListStyle
);
392 (*aIter
++)->addShape( rFilterBase
, pTheme
, rxShapes
, aChildTransformation
, getFillProperties(), NULL
, pShapeMap
);
396 Reference
< XShape
> Shape::createAndInsert(
397 ::oox::core::XmlFilterBase
& rFilterBase
,
398 const OUString
& rServiceName
,
400 const ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShapes
>& rxShapes
,
401 const awt::Rectangle
* /* pShapeRect */,
403 bool bDoNotInsertEmptyTextBody
,
404 basegfx::B2DHomMatrix
& aParentTransformation
,
405 FillProperties
& rShapeOrParentShapeFillProps
)
407 bool bIsEmbMedia
= false;
408 SAL_INFO("oox.drawingml", OSL_THIS_FUNC
<< " id: " << msId
);
410 // tdf#90403 PowerPoint ignores a:ext cx and cy values of p:xfrm, and uses real table width and height
411 if ( mpTablePropertiesPtr
.get() && rServiceName
== "com.sun.star.drawing.TableShape" )
414 for( std::vector
< sal_Int32
>::const_iterator
aTableColIter(mpTablePropertiesPtr
->getTableGrid().begin());
415 aTableColIter
!= mpTablePropertiesPtr
->getTableGrid().end(); ++aTableColIter
)
417 maSize
.Width
+= *aTableColIter
;
420 for( std::vector
< ::oox::drawingml::table::TableRow
>::const_iterator
aTableRowIter(mpTablePropertiesPtr
->getTableRows().begin());
421 aTableRowIter
!= mpTablePropertiesPtr
->getTableRows().end(); ++aTableRowIter
)
423 maSize
.Height
+= (*aTableRowIter
).getHeight();
427 awt::Rectangle
aShapeRectHmm( maPosition
.X
/ EMU_PER_HMM
, maPosition
.Y
/ EMU_PER_HMM
, maSize
.Width
/ EMU_PER_HMM
, maSize
.Height
/ EMU_PER_HMM
);
429 OUString aServiceName
;
430 if( rServiceName
== "com.sun.star.drawing.GraphicObjectShape" &&
431 mpGraphicPropertiesPtr
&& !mpGraphicPropertiesPtr
->m_sMediaPackageURL
.isEmpty())
433 aServiceName
= finalizeServiceName( rFilterBase
, "com.sun.star.presentation.MediaShape", aShapeRectHmm
);
438 aServiceName
= finalizeServiceName( rFilterBase
, rServiceName
, aShapeRectHmm
);
440 bool bIsCustomShape
= ( aServiceName
== "com.sun.star.drawing.CustomShape" ||
441 aServiceName
== "com.sun.star.drawing.ConnectorShape" );
442 bool bUseRotationTransform
= ( !mbWps
||
443 aServiceName
== "com.sun.star.drawing.LineShape" ||
444 aServiceName
== "com.sun.star.drawing.GroupShape" ||
448 basegfx::B2DHomMatrix aTransformation
;
450 if( maSize
.Width
!= 1 || maSize
.Height
!= 1)
452 // take care there are no zeros used by error
453 aTransformation
.scale(
454 maSize
.Width
? maSize
.Width
: 1.0,
455 maSize
.Height
? maSize
.Height
: 1.0 );
458 if( mbFlipH
|| mbFlipV
|| mnRotation
!= 0)
460 // calculate object's center
461 basegfx::B2DPoint
aCenter(0.5, 0.5);
462 aCenter
*= aTransformation
;
464 // center object at origin
465 aTransformation
.translate( -aCenter
.getX(), -aCenter
.getY() );
467 if( !bIsCustomShape
&& ( mbFlipH
|| mbFlipV
) )
469 // mirror around object's center
470 aTransformation
.scale( mbFlipH
? -1.0 : 1.0, mbFlipV
? -1.0 : 1.0 );
473 if( bUseRotationTransform
&& mnRotation
!= 0 )
475 // rotate around object's center
476 aTransformation
.rotate( F_PI180
* ( (double)mnRotation
/ 60000.0 ) );
479 // move object back from center
480 aTransformation
.translate( aCenter
.getX(), aCenter
.getY() );
483 bool bInGroup
= !aParentTransformation
.isIdentity();
484 if( maPosition
.X
!= 0 || maPosition
.Y
!= 0)
486 // if global position is used, add it to transformation
487 if (mbWps
&& !bInGroup
)
488 aTransformation
.translate( maPosition
.X
* EMU_PER_HMM
, maPosition
.Y
* EMU_PER_HMM
);
490 aTransformation
.translate( maPosition
.X
, maPosition
.Y
);
493 aTransformation
= aParentTransformation
*aTransformation
;
494 aParentTransformation
= aTransformation
;
495 aTransformation
.scale(1/double(EMU_PER_HMM
), 1/double(EMU_PER_HMM
));
497 // special for lineshape
498 if ( aServiceName
== "com.sun.star.drawing.LineShape" )
500 ::basegfx::B2DPolygon aPoly
;
501 aPoly
.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
502 aPoly
.insert( 1, ::basegfx::B2DPoint( maSize
.Width
? 1 : 0, maSize
.Height
? 1 : 0 ) );
503 aPoly
.transform( aTransformation
);
505 // now creating the corresponding PolyPolygon
506 sal_Int32 i
, nNumPoints
= aPoly
.count();
507 uno::Sequence
< awt::Point
> aPointSequence( nNumPoints
);
508 awt::Point
* pPoints
= aPointSequence
.getArray();
509 uno::Reference
<lang::XServiceInfo
> xModelInfo(rFilterBase
.getModel(), uno::UNO_QUERY
);
510 bool bIsWriter
= xModelInfo
->supportsService("com.sun.star.text.TextDocument");
511 for( i
= 0; i
< nNumPoints
; ++i
)
513 const ::basegfx::B2DPoint
aPoint( aPoly
.getB2DPoint( i
) );
514 if (bIsWriter
&& bInGroup
)
515 // Writer's draw page is in twips, and these points get passed
516 // to core without any unit conversion when Writer
517 // postprocesses only the group shape itself.
518 pPoints
[i
] = awt::Point(static_cast<sal_Int32
>(convertMm100ToTwip(aPoint
.getX())), static_cast<sal_Int32
>(convertMm100ToTwip(aPoint
.getY())));
520 pPoints
[i
] = awt::Point(static_cast<sal_Int32
>(aPoint
.getX()), static_cast<sal_Int32
>(aPoint
.getY()));
522 uno::Sequence
< uno::Sequence
< awt::Point
> > aPolyPolySequence( 1 );
523 aPolyPolySequence
.getArray()[ 0 ] = aPointSequence
;
525 maShapeProperties
.setProperty(PROP_PolyPolygon
, aPolyPolySequence
);
527 else if ( aServiceName
== "com.sun.star.drawing.ConnectorShape" )
529 ::basegfx::B2DPolygon aPoly
;
530 aPoly
.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
531 aPoly
.insert( 1, ::basegfx::B2DPoint( maSize
.Width
? 1 : 0, maSize
.Height
? 1 : 0 ) );
532 aPoly
.transform( aTransformation
);
534 basegfx::B2DPoint
aStartPosition( aPoly
.getB2DPoint( 0 ) );
535 basegfx::B2DPoint
aEndPosition( aPoly
.getB2DPoint( 1 ) );
536 awt::Point
aAWTStartPosition( static_cast< sal_Int32
>( aStartPosition
.getX() ), static_cast< sal_Int32
>( aStartPosition
.getY() ) );
537 awt::Point
aAWTEndPosition( static_cast< sal_Int32
>( aEndPosition
.getX() ), static_cast< sal_Int32
>( aEndPosition
.getY() ) );
539 maShapeProperties
.setProperty(PROP_StartPosition
, aAWTStartPosition
);
540 maShapeProperties
.setProperty(PROP_EndPosition
, aAWTEndPosition
);
544 // now set transformation for this object
545 HomogenMatrix3 aMatrix
;
547 aMatrix
.Line1
.Column1
= aTransformation
.get(0,0);
548 aMatrix
.Line1
.Column2
= aTransformation
.get(0,1);
549 aMatrix
.Line1
.Column3
= aTransformation
.get(0,2);
551 aMatrix
.Line2
.Column1
= aTransformation
.get(1,0);
552 aMatrix
.Line2
.Column2
= aTransformation
.get(1,1);
553 aMatrix
.Line2
.Column3
= aTransformation
.get(1,2);
555 aMatrix
.Line3
.Column1
= aTransformation
.get(2,0);
556 aMatrix
.Line3
.Column2
= aTransformation
.get(2,1);
557 aMatrix
.Line3
.Column3
= aTransformation
.get(2,2);
559 maShapeProperties
.setProperty(PROP_Transformation
, aMatrix
);
562 Reference
< lang::XMultiServiceFactory
> xServiceFact( rFilterBase
.getModel(), UNO_QUERY_THROW
);
564 mxShape
= Reference
< drawing::XShape
>( xServiceFact
->createInstance( aServiceName
), UNO_QUERY_THROW
);
566 Reference
< XPropertySet
> xSet( mxShape
, UNO_QUERY
);
567 if( mxShape
.is() && xSet
.is() )
569 if( !msName
.isEmpty() )
571 Reference
< container::XNamed
> xNamed( mxShape
, UNO_QUERY
);
573 xNamed
->setName( msName
);
575 if (aServiceName
!= "com.sun.star.text.TextFrame")
576 rxShapes
->add( mxShape
);
578 if ( mbHidden
|| mbHiddenMasterShape
)
580 SAL_INFO("oox.drawingml", OSL_THIS_FUNC
<< "invisible shape with id: " << msId
);
581 const OUString
sVisible( "Visible" );
582 xSet
->setPropertyValue( sVisible
, Any( sal_False
) );
585 ActionLockGuard
const alg(mxShape
);
587 // sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
590 uno::Reference
< text::XText
> xText( mxShape
, uno::UNO_QUERY
);
594 xText
->setString( aEmpty
);
598 const GraphicHelper
& rGraphicHelper
= rFilterBase
.getGraphicHelper();
600 LineProperties aLineProperties
;
601 aLineProperties
.maLineFill
.moFillType
= XML_noFill
;
602 sal_Int32 nLinePhClr
= -1;
603 FillProperties aFillProperties
;
604 aFillProperties
.moFillType
= XML_noFill
;
605 sal_Int32 nFillPhClr
= -1;
606 EffectProperties aEffectProperties
;
607 // TODO: use ph color when applying effect properties
608 //sal_Int32 nEffectPhClr = -1;
610 // First apply reference shape's properties (shape on the master slide)
611 aFillProperties
.assignUsed( *mpShapeRefFillPropPtr
);
612 aLineProperties
.assignUsed( *mpShapeRefLinePropPtr
);
613 aEffectProperties
.assignUsed( *mpShapeRefEffectPropPtr
);
617 if( const ShapeStyleRef
* pLineRef
= getShapeStyleRef( XML_lnRef
) )
619 if( const LineProperties
* pLineProps
= pTheme
->getLineStyle( pLineRef
->mnThemedIdx
) )
620 aLineProperties
.assignUsed( *pLineProps
);
621 nLinePhClr
= pLineRef
->maPhClr
.getColor( rGraphicHelper
);
623 // Store style-related properties to InteropGrabBag to be able to export them back
624 Sequence
< PropertyValue
> aProperties( 7 );
625 PUT_PROP( aProperties
, 0, "SchemeClr", pLineRef
->maPhClr
.getSchemeName() );
626 PUT_PROP( aProperties
, 1, "Idx", pLineRef
->mnThemedIdx
);
627 PUT_PROP( aProperties
, 2, "Color", nLinePhClr
);
628 PUT_PROP( aProperties
, 3, "LineStyle", aLineProperties
.getLineStyle() );
629 PUT_PROP( aProperties
, 4, "LineJoint", aLineProperties
.getLineJoint() );
630 PUT_PROP( aProperties
, 5, "LineWidth", aLineProperties
.getLineWidth() );
631 PUT_PROP( aProperties
, 6, "Transformations", pLineRef
->maPhClr
.getTransformations() );
632 putPropertyToGrabBag( "StyleLnRef", Any( aProperties
) );
634 if( const ShapeStyleRef
* pFillRef
= getShapeStyleRef( XML_fillRef
) )
636 if( const FillProperties
* pFillProps
= pTheme
->getFillStyle( pFillRef
->mnThemedIdx
) )
637 aFillProperties
.assignUsed( *pFillProps
);
638 nFillPhClr
= pFillRef
->maPhClr
.getColor( rGraphicHelper
);
640 OUString sColorScheme
= pFillRef
->maPhClr
.getSchemeName();
641 if( !sColorScheme
.isEmpty() )
643 Sequence
< PropertyValue
> aProperties(4);
644 PUT_PROP( aProperties
, 0, "SchemeClr", sColorScheme
);
645 PUT_PROP( aProperties
, 1, "Idx", pFillRef
->mnThemedIdx
);
646 PUT_PROP( aProperties
, 2, "Color", nFillPhClr
);
647 PUT_PROP( aProperties
, 3, "Transformations", pFillRef
->maPhClr
.getTransformations() );
649 putPropertyToGrabBag( "StyleFillRef", Any( aProperties
) );
652 if( const ShapeStyleRef
* pEffectRef
= getShapeStyleRef( XML_effectRef
) )
654 if( const EffectProperties
* pEffectProps
= pTheme
->getEffectStyle( pEffectRef
->mnThemedIdx
) )
655 aEffectProperties
.assignUsed( *pEffectProps
);
656 // TODO: use ph color when applying effect properties
657 // nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
659 // Store style-related properties to InteropGrabBag to be able to export them back
660 Sequence
< PropertyValue
> aProperties( 3 );
661 PUT_PROP( aProperties
, 0, "SchemeClr", pEffectRef
->maPhClr
.getSchemeName() );
662 PUT_PROP( aProperties
, 1, "Idx", pEffectRef
->mnThemedIdx
);
663 PUT_PROP( aProperties
, 2, "Transformations", pEffectRef
->maPhClr
.getTransformations() );
664 putPropertyToGrabBag( "StyleEffectRef", Any( aProperties
) );
668 aLineProperties
.assignUsed( getLineProperties() );
670 // group fill inherits from parent
671 if ( getFillProperties().moFillType
.has() && getFillProperties().moFillType
.get() == XML_grpFill
)
672 getFillProperties().assignUsed( rShapeOrParentShapeFillProps
);
673 aFillProperties
.assignUsed( getFillProperties() );
674 aEffectProperties
.assignUsed ( getEffectProperties() );
676 ShapePropertyMap
aShapeProps( rFilterBase
.getModelObjectHelper() );
678 // add properties from textbody to shape properties
679 if( mpTextBody
.get() )
681 mpTextBody
->getTextProperties().pushRotationAdjustments();
682 aShapeProps
.assignUsed( mpTextBody
->getTextProperties().maPropertyMap
);
683 // Push char properties as well - specifically useful when this is a placeholder
684 if( mpMasterTextListStyle
&& mpMasterTextListStyle
->getListStyle()[0]->getTextCharacterProperties().moHeight
.has() )
685 aShapeProps
.setProperty(PROP_CharHeight
, GetFontHeight( mpMasterTextListStyle
->getListStyle()[0]->getTextCharacterProperties().moHeight
.get() ));
688 // applying properties
689 aShapeProps
.assignUsed( getShapeProperties() );
690 aShapeProps
.assignUsed( maDefaultShapeProperties
);
691 if ( bIsEmbMedia
|| aServiceName
== "com.sun.star.drawing.GraphicObjectShape" || aServiceName
== "com.sun.star.drawing.OLE2Shape" )
692 mpGraphicPropertiesPtr
->pushToPropMap( aShapeProps
, rGraphicHelper
);
693 if ( mpTablePropertiesPtr
.get() && aServiceName
== "com.sun.star.drawing.TableShape" )
694 mpTablePropertiesPtr
->pushToPropSet( rFilterBase
, xSet
, mpMasterTextListStyle
);
695 aFillProperties
.pushToPropMap( aShapeProps
, rGraphicHelper
, mnRotation
, nFillPhClr
, mbFlipH
, mbFlipV
);
696 aLineProperties
.pushToPropMap( aShapeProps
, rGraphicHelper
, nLinePhClr
);
697 // TODO: use ph color when applying effect properties
698 aEffectProperties
.pushToPropMap( aShapeProps
, rGraphicHelper
);
700 // applying autogrowheight property before setting shape size, because
701 // the shape size might be changed if currently autogrowheight is true
702 // we must also check that the PropertySet supports the property.
703 Reference
< XPropertySetInfo
> xSetInfo( xSet
->getPropertySetInfo() );
704 const OUString
& rPropName
= PropertyMap::getPropertyName( PROP_TextAutoGrowHeight
);
705 if( xSetInfo
.is() && xSetInfo
->hasPropertyByName( rPropName
) )
706 if( aShapeProps
.hasProperty( PROP_TextAutoGrowHeight
) )
707 xSet
->setPropertyValue( rPropName
, Any( false ) );
709 // do not set properties at a group shape (this causes
710 // assertions from svx) ...
711 if( aServiceName
!= "com.sun.star.drawing.GroupShape" )
713 if (aServiceName
== "com.sun.star.text.TextFrame")
715 if (mpCustomShapePropertiesPtr
&& mpCustomShapePropertiesPtr
->getShapeTypeOverride())
717 uno::Reference
<beans::XPropertySet
> propertySet (mxShape
, uno::UNO_QUERY
);
718 uno::Sequence
<beans::PropertyValue
> aGrabBag
;
719 propertySet
->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag
;
720 sal_Int32 length
= aGrabBag
.getLength();
721 aGrabBag
.realloc( length
+1);
722 aGrabBag
[length
].Name
= "mso-orig-shape-type";
723 const uno::Sequence
< sal_Int8
> aNameSeq
=
724 mpCustomShapePropertiesPtr
->getShapePresetTypeName();
725 OUString
sShapePresetTypeName(reinterpret_cast< const char* >(
726 aNameSeq
.getConstArray()), aNameSeq
.getLength(), RTL_TEXTENCODING_UTF8
);
727 aGrabBag
[length
].Value
= uno::makeAny(sShapePresetTypeName
);
728 propertySet
->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag
));
730 //If the text box has links then save the link information so that
731 //it can be accessed in DomainMapper_Impl.cxx while chaining the text frames.
732 if (this->isLinkedTxbx())
734 uno::Reference
<beans::XPropertySet
> propertySet (mxShape
, uno::UNO_QUERY
);
735 uno::Sequence
<beans::PropertyValue
> aGrabBag
;
736 propertySet
->getPropertyValue("FrameInteropGrabBag") >>= aGrabBag
;
737 sal_Int32 length
= aGrabBag
.getLength();
738 aGrabBag
.realloc( length
+ 3 );
739 aGrabBag
[length
].Name
= "TxbxHasLink";
740 aGrabBag
[length
].Value
= uno::makeAny(this->isLinkedTxbx());
741 aGrabBag
[length
+ 1 ].Name
= "Txbx-Id";
742 aGrabBag
[length
+ 1 ].Value
= uno::makeAny(this->getLinkedTxbxAttributes().id
);
743 aGrabBag
[length
+ 2 ].Name
= "Txbx-Seq";
744 aGrabBag
[length
+ 2 ].Value
= uno::makeAny(this->getLinkedTxbxAttributes().seq
);
745 propertySet
->setPropertyValue("FrameInteropGrabBag",uno::makeAny(aGrabBag
));
748 // TextFrames have BackColor, not FillColor
749 if (aShapeProps
.hasProperty(PROP_FillColor
))
751 aShapeProps
.setProperty(PROP_BackColor
, aShapeProps
.getProperty(PROP_FillColor
));
752 aShapeProps
.erase(PROP_FillColor
);
754 // TextFrames have BackColorTransparency, not FillTransparence
755 if (aShapeProps
.hasProperty(PROP_FillTransparence
))
757 aShapeProps
.setProperty(PROP_BackColorTransparency
, aShapeProps
.getProperty(PROP_FillTransparence
));
758 aShapeProps
.erase(PROP_FillTransparence
);
760 // TextFrames have BackGrahicURL, not FillBitmapURL
761 if (aShapeProps
.hasProperty(PROP_FillBitmapURL
))
763 aShapeProps
.setProperty(PROP_BackGraphicURL
, aShapeProps
.getProperty(PROP_FillBitmapURL
));
764 aShapeProps
.erase(PROP_FillBitmapURL
);
766 if (aShapeProps
.hasProperty(PROP_FillBitmapName
))
768 uno::Any aAny
= aShapeProps
.getProperty(PROP_FillBitmapName
);
769 aShapeProps
.setProperty(PROP_BackGraphicURL
, rFilterBase
.getModelObjectHelper().getFillBitmapUrl( aAny
.get
<OUString
>() ));
770 // aShapeProps.erase(PROP_FillBitmapName); // Maybe, leave the name as well
772 // And no LineColor property; individual borders can have colors
773 if (aShapeProps
.hasProperty(PROP_LineColor
))
775 uno::Reference
<beans::XPropertySet
> xPropertySet(mxShape
, uno::UNO_QUERY
);
776 static const sal_Int32 aBorders
[] =
778 PROP_TopBorder
, PROP_LeftBorder
, PROP_BottomBorder
, PROP_RightBorder
780 for (unsigned int i
= 0; i
< SAL_N_ELEMENTS(aBorders
); ++i
)
782 css::table::BorderLine2 aBorderLine
= xPropertySet
->getPropertyValue(PropertyMap::getPropertyName(aBorders
[i
])).get
<css::table::BorderLine2
>();
783 aBorderLine
.Color
= aShapeProps
.getProperty(PROP_LineColor
).get
<sal_Int32
>();
784 if (aLineProperties
.moLineWidth
.has())
785 aBorderLine
.LineWidth
= convertEmuToHmm(aLineProperties
.moLineWidth
.get());
786 aShapeProps
.setProperty(aBorders
[i
], uno::makeAny(aBorderLine
));
788 aShapeProps
.erase(PROP_LineColor
);
792 uno::Reference
<beans::XPropertySet
> xPropertySet(mxShape
, uno::UNO_QUERY
);
793 const OUString aGrabBagPropName
= "FrameInteropGrabBag";
794 uno::Sequence
<beans::PropertyValue
> aGrabBag
;
795 xPropertySet
->getPropertyValue(aGrabBagPropName
) >>= aGrabBag
;
796 beans::PropertyValue aPair
;
797 aPair
.Name
= "mso-rotation-angle";
798 aPair
.Value
= uno::makeAny(mnRotation
);
799 if (aGrabBag
.hasElements())
801 sal_Int32 nLength
= aGrabBag
.getLength();
802 aGrabBag
.realloc(nLength
+ 1);
803 aGrabBag
[nLength
] = aPair
;
810 xPropertySet
->setPropertyValue(aGrabBagPropName
, uno::makeAny(aGrabBag
));
812 // TextFrames have ShadowFormat, not individual shadow properties.
813 boost::optional
<sal_Int32
> oShadowDistance
;
814 if (aShapeProps
.hasProperty(PROP_ShadowXDistance
))
816 oShadowDistance
= aShapeProps
.getProperty(PROP_ShadowXDistance
).get
<sal_Int32
>();
817 aShapeProps
.erase(PROP_ShadowXDistance
);
819 if (aShapeProps
.hasProperty(PROP_ShadowYDistance
))
821 // There is a single 'dist' attribute, so no need to count the avg of x and y.
822 aShapeProps
.erase(PROP_ShadowYDistance
);
824 boost::optional
<sal_Int32
> oShadowColor
;
825 if (aShapeProps
.hasProperty(PROP_ShadowColor
))
827 oShadowColor
= aShapeProps
.getProperty(PROP_ShadowColor
).get
<sal_Int32
>();
828 aShapeProps
.erase(PROP_ShadowColor
);
830 if (aShapeProps
.hasProperty(PROP_Shadow
))
831 aShapeProps
.erase(PROP_Shadow
);
833 if (oShadowDistance
|| oShadowColor
|| aEffectProperties
.maShadow
.moShadowDir
.has())
835 css::table::ShadowFormat aFormat
;
837 aFormat
.Color
= *oShadowColor
;
838 if (aEffectProperties
.maShadow
.moShadowDir
.has())
840 css::table::ShadowLocation nLocation
= css::table::ShadowLocation_NONE
;
841 switch (aEffectProperties
.maShadow
.moShadowDir
.get())
844 nLocation
= css::table::ShadowLocation_TOP_LEFT
;
847 nLocation
= css::table::ShadowLocation_TOP_RIGHT
;
850 nLocation
= css::table::ShadowLocation_BOTTOM_LEFT
;
853 nLocation
= css::table::ShadowLocation_BOTTOM_RIGHT
;
856 aFormat
.Location
= nLocation
;
858 aFormat
.ShadowWidth
= *oShadowDistance
;
859 aShapeProps
.setProperty(PROP_ShadowFormat
, uno::makeAny(aFormat
));
864 aShapeProps
.setProperty(PROP_TextBox
, uno::makeAny(true));
867 if (aServiceName
!= "com.sun.star.text.TextFrame" && isLinkedTxbx())
869 uno::Reference
<beans::XPropertySet
> propertySet (mxShape
, uno::UNO_QUERY
);
870 uno::Sequence
<beans::PropertyValue
> aGrabBag
;
871 propertySet
->getPropertyValue("InteropGrabBag") >>= aGrabBag
;
872 sal_Int32 length
= aGrabBag
.getLength();
873 aGrabBag
.realloc( length
+ 3 );
874 aGrabBag
[length
].Name
= "TxbxHasLink";
875 aGrabBag
[length
].Value
= uno::makeAny(this->isLinkedTxbx());
876 aGrabBag
[length
+ 1 ].Name
= "Txbx-Id";
877 aGrabBag
[length
+ 1 ].Value
= uno::makeAny(this->getLinkedTxbxAttributes().id
);
878 aGrabBag
[length
+ 2 ].Name
= "Txbx-Seq";
879 aGrabBag
[length
+ 2 ].Value
= uno::makeAny(this->getLinkedTxbxAttributes().seq
);
880 propertySet
->setPropertyValue("InteropGrabBag",uno::makeAny(aGrabBag
));
883 PropertySet( xSet
).setProperties( aShapeProps
);
886 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
887 if (aServiceName
== "com.sun.star.drawing.LineShape")
889 // It seems the position and size for lines inside a locked canvas is absolute.
890 mxShape
->setPosition(awt::Point(aShapeRectHmm
.X
, aShapeRectHmm
.Y
));
891 mxShape
->setSize(awt::Size(aShapeRectHmm
.Width
, aShapeRectHmm
.Height
));
895 // Store original fill and line colors of the shape and the theme color name to InteropGrabBag
896 Sequence
< PropertyValue
> aProperties( 6 ); //allocate the maximum possible number of slots
898 PUT_PROP( aProperties
, 0, "OriginalSolidFillClr", aShapeProps
.getProperty(PROP_FillColor
) );
899 PUT_PROP( aProperties
, 1, "OriginalLnSolidFillClr", aShapeProps
.getProperty(PROP_LineColor
) );
900 OUString sColorFillScheme
= aFillProperties
.maFillColor
.getSchemeName();
901 if( !aFillProperties
.maFillColor
.isPlaceHolder() && !sColorFillScheme
.isEmpty() )
903 PUT_PROP( aProperties
, nSize
, "SpPrSolidFillSchemeClr", sColorFillScheme
);
905 PUT_PROP( aProperties
, nSize
, "SpPrSolidFillSchemeClrTransformations",
906 aFillProperties
.maFillColor
.getTransformations() );
909 OUString sLnColorFillScheme
= aLineProperties
.maLineFill
.maFillColor
.getSchemeName();
910 if( !aLineProperties
.maLineFill
.maFillColor
.isPlaceHolder() && !sLnColorFillScheme
.isEmpty() )
912 PUT_PROP( aProperties
, nSize
, "SpPrLnSolidFillSchemeClr", sLnColorFillScheme
);
914 PUT_PROP( aProperties
, nSize
, "SpPrLnSolidFillSchemeClrTransformations",
915 aLineProperties
.maLineFill
.maFillColor
.getTransformations() );
918 aProperties
.realloc( nSize
); //shrink the Sequence if we didn't use all the slots
919 putPropertiesToGrabBag( aProperties
);
921 // Store original gradient fill of the shape to InteropGrabBag
922 // LibreOffice doesn't support all the kinds of gradient so we save its complete definition
923 if( aShapeProps
.hasProperty( PROP_FillGradient
) )
925 Sequence
< PropertyValue
> aGradientStops( aFillProperties
.maGradientProps
.maGradientStops
.size() );
926 ::std::map
< double, Color
>::iterator aIt
= aFillProperties
.maGradientProps
.maGradientStops
.begin();
927 for( sal_uInt32 i
= 0; i
< aFillProperties
.maGradientProps
.maGradientStops
.size(); ++i
)
928 { // for each stop in the gradient definition:
931 Sequence
< PropertyValue
> aGradientStop( 3 );
932 PUT_PROP( aGradientStop
, 0, "Pos", aIt
->first
);
934 OUString sStopColorScheme
= aIt
->second
.getSchemeName();
935 if( sStopColorScheme
.isEmpty() )
938 PUT_PROP( aGradientStop
, 1, "RgbClr", aIt
->second
.getColor( rGraphicHelper
, nFillPhClr
) );
939 // in the case of a RGB color, transformations are already applied to
940 // the color with the exception of alpha transformations. We only need
941 // to keep the transparency value to calculate the alpha value later.
942 if( aIt
->second
.hasTransparency() )
944 PUT_PROP( aGradientStop
, 2, "Transparency", aIt
->second
.getTransparency() );
949 // save color with scheme name
950 PUT_PROP( aGradientStop
, 1, "SchemeClr", sStopColorScheme
);
951 // save all color transformations
952 PUT_PROP( aGradientStop
, 2, "Transformations", aIt
->second
.getTransformations() );
955 PUT_PROP( aGradientStops
, i
, OUString::number( i
), aGradientStop
);
958 // If getFillProperties.moFillType is unused that means gradient is defined by a theme
959 // which is already saved into StyleFillRef property, so no need to save the explicit values too
960 if( getFillProperties().moFillType
.has() )
961 putPropertyToGrabBag( "GradFillDefinition", Any( aGradientStops
) );
962 putPropertyToGrabBag( "OriginalGradFill", aShapeProps
.getProperty(PROP_FillGradient
) );
965 // store unsupported effect attributes in the grab bag
966 if( aEffectProperties
.maEffects
.size() > 0 )
968 Sequence
< PropertyValue
> aEffects( aEffectProperties
.maEffects
.size() );
970 for( boost::ptr_vector
< Effect
>::iterator it
= aEffectProperties
.maEffects
.begin();
971 it
!= aEffectProperties
.maEffects
.end(); ++it
)
973 PropertyValue aEffect
= it
->getEffect();
974 if( !aEffect
.Name
.isEmpty() )
976 Sequence
< PropertyValue
> aEffectsGrabBag( 3 );
977 PUT_PROP( aEffectsGrabBag
, 0, "Attribs", aEffect
.Value
);
979 Color
& aColor( it
->moColor
);
980 OUString sColorScheme
= aColor
.getSchemeName();
981 if( sColorScheme
.isEmpty() )
983 // RGB color and transparency value
984 PUT_PROP( aEffectsGrabBag
, 1, "RgbClr",
985 aColor
.getColor( rGraphicHelper
, nFillPhClr
) );
986 PUT_PROP( aEffectsGrabBag
, 2, "RgbClrTransparency",
987 aColor
.getTransparency() );
991 // scheme color with name and transformations
992 PUT_PROP( aEffectsGrabBag
, 1, "SchemeClr", sColorScheme
);
993 PUT_PROP( aEffectsGrabBag
, 2, "SchemeClrTransformations",
994 aColor
.getTransformations() );
996 PUT_PROP( aEffects
, i
, aEffect
.Name
, aEffectsGrabBag
);
1000 putPropertyToGrabBag( "EffectProperties", Any( aEffects
) );
1003 // add 3D effects if any
1004 Sequence
< PropertyValue
> aCamera3DEffects
= get3DProperties().getCameraAttributes();
1005 Sequence
< PropertyValue
> aLightRig3DEffects
= get3DProperties().getLightRigAttributes();
1006 Sequence
< PropertyValue
> aShape3DEffects
= get3DProperties().getShape3DAttributes( rGraphicHelper
, nFillPhClr
);
1007 if( aCamera3DEffects
.getLength() > 0 || aLightRig3DEffects
.getLength() > 0 || aShape3DEffects
.getLength() > 0 )
1009 Sequence
< PropertyValue
> a3DEffectsGrabBag( 3 );
1010 PUT_PROP( a3DEffectsGrabBag
, 0, "Camera", Any( aCamera3DEffects
) );
1011 PUT_PROP( a3DEffectsGrabBag
, 1, "LightRig", Any( aLightRig3DEffects
) );
1012 PUT_PROP( a3DEffectsGrabBag
, 2, "Shape3D", Any( aShape3DEffects
) );
1013 putPropertyToGrabBag( "3DEffectProperties", Any( a3DEffectsGrabBag
) );
1016 // store bitmap artistic effects in the grab bag
1017 if( !mpGraphicPropertiesPtr
->maBlipProps
.maEffect
.isEmpty() )
1018 putPropertyToGrabBag( "ArtisticEffectProperties",
1019 Any( mpGraphicPropertiesPtr
->maBlipProps
.maEffect
.getEffect() ) );
1022 else if( mbLockedCanvas
)
1024 //If we have aServiceName as "com.sun.star.drawing.GroupShape" and lockedCanvas
1025 putPropertyToGrabBag( "LockedCanvas", Any( true ) );
1028 // These can have a custom geometry, so position should be set here,
1029 // after creation but before custom shape handling, using the position
1030 // we got from the caller.
1031 if (mbWps
&& aServiceName
== "com.sun.star.drawing.LineShape")
1032 mxShape
->setPosition(maPosition
);
1034 if( bIsCustomShape
)
1037 mpCustomShapePropertiesPtr
->setMirroredX( true );
1039 mpCustomShapePropertiesPtr
->setMirroredY( true );
1042 sal_Int32 nTextRotateAngle
= static_cast< sal_Int32
>( getTextBody()->getTextProperties().moRotation
.get( 0 ) );
1043 /* OOX measures text rotation clockwise in 1/60000th degrees,
1044 relative to the containing shape. setTextRotateAngle wants
1045 degrees anticlockwise. */
1046 mpCustomShapePropertiesPtr
->setTextRotateAngle( -1 * nTextRotateAngle
/ 60000 );
1049 SAL_INFO("oox.cscode", "==cscode== shape name: '" << msName
<< "'");
1050 SAL_INFO("oox.csdata", "==csdata== shape name: '" << msName
<< "'");
1051 mpCustomShapePropertiesPtr
->pushToPropSet( rFilterBase
, xSet
, mxShape
, maSize
);
1053 else if( getTextBody() )
1054 getTextBody()->getTextProperties().pushVertSimulation();
1056 PropertySet
aPropertySet(mxShape
);
1057 if ( !bUseRotationTransform
&& mnRotation
!= 0 )
1059 // use the same logic for rotation from VML exporter (SimpleShape::implConvertAndInsert at vmlshape.cxx)
1060 aPropertySet
.setAnyProperty( PROP_RotateAngle
, makeAny( sal_Int32( NormAngle360( mnRotation
/ -600 ) ) ) );
1061 aPropertySet
.setAnyProperty( PROP_HoriOrientPosition
, makeAny( maPosition
.X
) );
1062 aPropertySet
.setAnyProperty( PROP_VertOrientPosition
, makeAny( maPosition
.Y
) );
1065 // in some cases, we don't have any text body.
1066 if( getTextBody() && ( !bDoNotInsertEmptyTextBody
|| !mpTextBody
->isEmpty() ) )
1068 Reference
< XText
> xText( mxShape
, UNO_QUERY
);
1069 if ( xText
.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
1071 TextCharacterProperties aCharStyleProperties
;
1072 if( const ShapeStyleRef
* pFontRef
= getShapeStyleRef( XML_fontRef
) )
1074 if( pFontRef
->mnThemedIdx
!= 0 )
1077 if( const TextCharacterProperties
* pCharProps
= pTheme
->getFontStyle( pFontRef
->mnThemedIdx
) )
1078 aCharStyleProperties
.assignUsed( *pCharProps
);
1079 SAL_INFO("oox.drawingml", OSL_THIS_FUNC
<< "use font color");
1080 aCharStyleProperties
.maCharColor
.assignIfUsed( pFontRef
->maPhClr
);
1084 Reference
< XTextCursor
> xAt
= xText
->createTextCursor();
1085 getTextBody()->insertAt( rFilterBase
, xText
, xAt
, aCharStyleProperties
, mpMasterTextListStyle
);
1090 // No drawingML text, but WPS text is expected: save the theme
1091 // character color on the shape, then.
1092 if(const ShapeStyleRef
* pFontRef
= getShapeStyleRef(XML_fontRef
))
1094 sal_Int32 nCharColor
= pFontRef
->maPhClr
.getColor(rGraphicHelper
);
1095 aPropertySet
.setAnyProperty(PROP_CharColor
, uno::makeAny(nCharColor
));
1101 finalizeXShape( rFilterBase
, rxShapes
);
1106 void Shape::keepDiagramCompatibilityInfo( XmlFilterBase
& rFilterBase
)
1110 if( !maDiagramDoms
.hasElements() )
1113 Reference
< XPropertySet
> xSet( mxShape
, UNO_QUERY_THROW
);
1114 Reference
< XPropertySetInfo
> xSetInfo( xSet
->getPropertySetInfo() );
1115 if ( !xSetInfo
.is() )
1118 const OUString aGrabBagPropName
= UNO_NAME_MISC_OBJ_INTEROPGRABBAG
;
1119 if( !xSetInfo
->hasPropertyByName( aGrabBagPropName
) )
1122 Sequence
< PropertyValue
> aGrabBag
;
1123 xSet
->getPropertyValue( aGrabBagPropName
) >>= aGrabBag
;
1125 // We keep the previous items, if present
1126 if ( aGrabBag
.hasElements() )
1128 sal_Int32 length
= aGrabBag
.getLength();
1129 aGrabBag
.realloc( length
+maDiagramDoms
.getLength() );
1131 for( sal_Int32 i
= 0; i
< maDiagramDoms
.getLength(); ++i
)
1132 aGrabBag
[length
+i
] = maDiagramDoms
[i
];
1134 xSet
->setPropertyValue( aGrabBagPropName
, Any( aGrabBag
) );
1136 xSet
->setPropertyValue( aGrabBagPropName
, Any( maDiagramDoms
) );
1138 xSet
->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True
) );
1139 xSet
->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True
) );
1141 // Replace existing shapes with a new Graphic Object rendered
1143 Reference
< XShape
> xShape( renderDiagramToGraphic( rFilterBase
) );
1144 Reference
< XShapes
> xShapes( mxShape
, UNO_QUERY_THROW
);
1145 while( xShapes
->hasElements() )
1146 xShapes
->remove( Reference
< XShape
> ( xShapes
->getByIndex( 0 ), UNO_QUERY_THROW
) );
1147 xShapes
->add( xShape
);
1149 catch( const Exception
& e
)
1151 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC
<< "Exception: " << e
.Message
);
1155 Reference
< XShape
> Shape::renderDiagramToGraphic( XmlFilterBase
& rFilterBase
)
1157 Reference
< XShape
> xShape
;
1161 if( !maDiagramDoms
.hasElements() )
1164 // Stream in which to place the rendered shape
1165 SvMemoryStream mpTempStream
;
1166 Reference
< io::XStream
> xStream( new utl::OStreamWrapper( mpTempStream
) );
1167 Reference
< io::XOutputStream
> xOutputStream( xStream
->getOutputStream() );
1170 OUString
sFormat( "SVM" );
1172 // Size of the rendering
1173 awt::Size aActualSize
= mxShape
->getSize();
1174 Size
aResolution( Application::GetDefaultDevice()->LogicToPixel( Size( 100, 100 ), MAP_CM
) );
1175 double fPixelsPer100thmm
= static_cast < double > ( aResolution
.Width() ) / 100000.0;
1176 awt::Size aSize
= awt::Size( static_cast < sal_Int32
> ( ( fPixelsPer100thmm
* aActualSize
.Width
) + 0.5 ),
1177 static_cast < sal_Int32
> ( ( fPixelsPer100thmm
* aActualSize
.Height
) + 0.5 ) );
1179 Sequence
< PropertyValue
> aFilterData( 4 );
1180 aFilterData
[ 0 ].Name
= "PixelWidth";
1181 aFilterData
[ 0 ].Value
<<= aSize
.Width
;
1182 aFilterData
[ 1 ].Name
= "PixelHeight";
1183 aFilterData
[ 1 ].Value
<<= aSize
.Height
;
1184 aFilterData
[ 2 ].Name
= "LogicalWidth";
1185 aFilterData
[ 2 ].Value
<<= aActualSize
.Width
;
1186 aFilterData
[ 3 ].Name
= "LogicalHeight";
1187 aFilterData
[ 3 ].Value
<<= aActualSize
.Height
;
1189 Sequence
< PropertyValue
> aDescriptor( 3 );
1190 aDescriptor
[ 0 ].Name
= "OutputStream";
1191 aDescriptor
[ 0 ].Value
<<= xOutputStream
;
1192 aDescriptor
[ 1 ].Name
= "FilterName";
1193 aDescriptor
[ 1 ].Value
<<= sFormat
;
1194 aDescriptor
[ 2 ].Name
= "FilterData";
1195 aDescriptor
[ 2 ].Value
<<= aFilterData
;
1197 Reference
< lang::XComponent
> xSourceDoc( mxShape
, UNO_QUERY_THROW
);
1198 Reference
< XGraphicExportFilter
> xGraphicExporter
= GraphicExportFilter::create( rFilterBase
.getComponentContext() );
1199 xGraphicExporter
->setSourceDocument( xSourceDoc
);
1200 xGraphicExporter
->filter( aDescriptor
);
1202 mpTempStream
.Seek( STREAM_SEEK_TO_BEGIN
);
1205 GraphicFilter
aFilter( false );
1206 if ( aFilter
.ImportGraphic( aGraphic
, "", mpTempStream
, GRFILTER_FORMAT_NOTFOUND
, NULL
, GraphicFilterImportFlags::NONE
, static_cast < Sequence
< PropertyValue
>* > ( NULL
), NULL
) != GRFILTER_OK
)
1208 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC
1209 << "Unable to import rendered stream into graphic object" );
1213 Reference
< graphic::XGraphic
> xGraphic( aGraphic
.GetXGraphic() );
1214 Reference
< lang::XMultiServiceFactory
> xServiceFact( rFilterBase
.getModel(), UNO_QUERY_THROW
);
1215 xShape
= Reference
< XShape
> ( xServiceFact
->createInstance( OUString( "com.sun.star.drawing.GraphicObjectShape" ) ), UNO_QUERY_THROW
);
1216 Reference
< XPropertySet
> xPropSet( xShape
, UNO_QUERY_THROW
);
1217 xPropSet
->setPropertyValue( OUString( "Graphic" ), Any( xGraphic
) );
1218 xPropSet
->setPropertyValue( OUString( "MoveProtect" ), Any( sal_True
) );
1219 xPropSet
->setPropertyValue( OUString( "SizeProtect" ), Any( sal_True
) );
1220 xPropSet
->setPropertyValue( OUString( "Name" ), Any( OUString( "RenderedShapes" ) ) );
1222 catch( const Exception
& e
)
1224 SAL_WARN( "oox.drawingml", OSL_THIS_FUNC
<< "Exception: " << e
.Message
);
1230 void Shape::setTextBody(const TextBodyPtr
& pTextBody
)
1232 mpTextBody
= pTextBody
;
1235 void Shape::setMasterTextListStyle( const TextListStylePtr
& pMasterTextListStyle
)
1237 SAL_INFO("oox.drawingml", OSL_THIS_FUNC
<< "set master text list style to shape id: " << msId
);
1239 mpMasterTextListStyle
= pMasterTextListStyle
;
1242 OUString
Shape::finalizeServiceName( XmlFilterBase
& rFilter
, const OUString
& rServiceName
, const awt::Rectangle
& rShapeRect
)
1244 OUString aServiceName
= rServiceName
;
1245 switch( meFrameType
)
1247 case FRAMETYPE_OLEOBJECT
:
1249 awt::Size
aOleSize( rShapeRect
.Width
, rShapeRect
.Height
);
1250 if( rFilter
.getOleObjectHelper().importOleObject( maShapeProperties
, *mxOleObjectInfo
, aOleSize
) )
1251 aServiceName
= "com.sun.star.drawing.OLE2Shape";
1253 // get the path to the representation graphic
1254 OUString aGraphicPath
;
1255 if( !mxOleObjectInfo
->maShapeId
.isEmpty() )
1256 if( ::oox::vml::Drawing
* pVmlDrawing
= rFilter
.getVmlDrawing() )
1257 if( const ::oox::vml::ShapeBase
* pVmlShape
= pVmlDrawing
->getShapes().getShapeById( mxOleObjectInfo
->maShapeId
, true ) )
1258 aGraphicPath
= pVmlShape
->getGraphicPath();
1260 // import and store the graphic
1261 if( !aGraphicPath
.isEmpty() )
1263 // Transfer shape's width and heightto graphicsfilter (can be used by WMF/EMF)
1264 WMF_EXTERNALHEADER aExtHeader
;
1265 aExtHeader
.mapMode
= 8; // MM_ANISOTROPIC
1266 aExtHeader
.xExt
= rShapeRect
.Width
;
1267 aExtHeader
.yExt
= rShapeRect
.Height
;
1269 Reference
< graphic::XGraphic
> xGraphic
= rFilter
.getGraphicHelper().importEmbeddedGraphic( aGraphicPath
, &aExtHeader
);
1271 maShapeProperties
.setProperty(PROP_Graphic
, xGraphic
);
1278 return aServiceName
;
1281 void Shape::finalizeXShape( XmlFilterBase
& rFilter
, const Reference
< XShapes
>& rxShapes
)
1283 switch( meFrameType
)
1285 case FRAMETYPE_CHART
:
1287 OSL_ENSURE( !mxChartShapeInfo
->maFragmentPath
.isEmpty(), "Shape::finalizeXShape - missing chart fragment" );
1288 if( mxShape
.is() && !mxChartShapeInfo
->maFragmentPath
.isEmpty() ) try
1290 // set the chart2 OLE class ID at the OLE shape
1291 PropertySet
aShapeProp( mxShape
);
1292 aShapeProp
.setProperty( PROP_CLSID
, OUString( "12dcae26-281f-416f-a234-c3086127382e" ) );
1294 // get the XModel interface of the embedded object from the OLE shape
1295 Reference
< frame::XModel
> xDocModel
;
1296 aShapeProp
.getProperty( xDocModel
, PROP_Model
);
1297 Reference
< chart2::XChartDocument
> xChartDoc( xDocModel
, UNO_QUERY_THROW
);
1299 // load the chart data from the XML fragment
1300 bool bMSO2007Doc
= rFilter
.isMSO2007Document();
1301 chart::ChartSpaceModel
aModel(bMSO2007Doc
);
1302 chart::ChartSpaceFragment
*pChartSpaceFragment
= new chart::ChartSpaceFragment(
1303 rFilter
, mxChartShapeInfo
->maFragmentPath
, aModel
);
1304 const OUString
aThemeOverrideFragmentPath( pChartSpaceFragment
->
1305 getFragmentPathFromFirstTypeFromOfficeDoc("themeOverride") );
1306 rFilter
.importFragment( pChartSpaceFragment
);
1307 ::oox::ppt::PowerPointImport
*pPowerPointImport
=
1308 dynamic_cast< ::oox::ppt::PowerPointImport
* >(&rFilter
);
1309 if (!aThemeOverrideFragmentPath
.isEmpty() && pPowerPointImport
)
1311 uno::Reference
< xml::sax::XFastSAXSerializable
> xDoc(
1312 rFilter
.importFragment(aThemeOverrideFragmentPath
), uno::UNO_QUERY_THROW
);
1313 ThemePtr pTheme
= pPowerPointImport
->getActualSlidePersist()->getTheme();
1314 rFilter
.importFragment(new ThemeOverrideFragmentHandler(
1315 rFilter
, aThemeOverrideFragmentPath
, *pTheme
), xDoc
);
1316 pPowerPointImport
->getActualSlidePersist()->setTheme(pTheme
);
1319 // convert imported chart model to chart document
1320 Reference
< drawing::XShapes
> xExternalPage
;
1321 if( !mxChartShapeInfo
->mbEmbedShapes
)
1322 xExternalPage
= rxShapes
;
1323 if( rFilter
.getChartConverter() )
1325 rFilter
.getChartConverter()->convertFromModel( rFilter
, aModel
, xChartDoc
, xExternalPage
, mxShape
->getPosition(), mxShape
->getSize() );
1326 if( !xChartDoc
->hasInternalDataProvider() )
1328 Reference
< chart2::data::XDataReceiver
> xDataRec( xChartDoc
, UNO_QUERY
);
1329 Reference
< chart2::data::XDataSource
> xData( xDataRec
->getUsedData(), UNO_QUERY
);
1330 if( xData
->getDataSequences().getLength() <= 0 || !xData
->getDataSequences()[0]->getValues().is() ||
1331 xData
->getDataSequences()[0]->getValues()->getData().getLength() <= 0 )
1333 rFilter
.useInternalChartDataTable( true );
1334 rFilter
.getChartConverter()->convertFromModel( rFilter
, aModel
, xChartDoc
, xExternalPage
, mxShape
->getPosition(), mxShape
->getSize() );
1335 rFilter
.useInternalChartDataTable( false );
1351 void Shape::putPropertyToGrabBag( const OUString
& sPropertyName
, const Any
& aPropertyValue
)
1353 PropertyValue pNewProperty
;
1354 pNewProperty
.Name
= sPropertyName
;
1355 pNewProperty
.Value
= aPropertyValue
;
1356 putPropertyToGrabBag( pNewProperty
);
1359 void Shape::putPropertyToGrabBag( const PropertyValue
& pProperty
)
1361 Reference
< XPropertySet
> xSet( mxShape
, UNO_QUERY
);
1362 Reference
< XPropertySetInfo
> xSetInfo( xSet
->getPropertySetInfo() );
1363 const OUString
& aGrabBagPropName
= OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG
);
1364 if( mxShape
.is() && xSet
.is() && xSetInfo
.is() && xSetInfo
->hasPropertyByName( aGrabBagPropName
) )
1366 Sequence
< PropertyValue
> aGrabBag
;
1367 xSet
->getPropertyValue( aGrabBagPropName
) >>= aGrabBag
;
1369 sal_Int32 length
= aGrabBag
.getLength();
1370 aGrabBag
.realloc( length
+ 1 );
1371 aGrabBag
[length
] = pProperty
;
1373 xSet
->setPropertyValue( aGrabBagPropName
, Any( aGrabBag
) );
1377 void Shape::putPropertiesToGrabBag( const Sequence
< PropertyValue
>& aProperties
)
1379 Reference
< XPropertySet
> xSet( mxShape
, UNO_QUERY
);
1380 Reference
< XPropertySetInfo
> xSetInfo( xSet
->getPropertySetInfo() );
1381 const OUString
& aGrabBagPropName
= OUString( UNO_NAME_MISC_OBJ_INTEROPGRABBAG
);
1382 if( mxShape
.is() && xSet
.is() && xSetInfo
.is() && xSetInfo
->hasPropertyByName( aGrabBagPropName
) )
1384 // get existing grab bag
1385 Sequence
< PropertyValue
> aGrabBag
;
1386 xSet
->getPropertyValue( aGrabBagPropName
) >>= aGrabBag
;
1387 sal_Int32 length
= aGrabBag
.getLength();
1389 // update grab bag size to contain the new items
1390 aGrabBag
.realloc( length
+ aProperties
.getLength() );
1392 // put the new items
1393 for( sal_Int32 i
=0; i
< aProperties
.getLength(); ++i
)
1395 aGrabBag
[length
+ i
].Name
= aProperties
[i
].Name
;
1396 aGrabBag
[length
+ i
].Value
= aProperties
[i
].Value
;
1399 // put it back to the shape
1400 xSet
->setPropertyValue( aGrabBagPropName
, Any( aGrabBag
) );
1404 uno::Sequence
< uno::Sequence
< uno::Any
> > Shape::resolveRelationshipsOfTypeFromOfficeDoc(core::XmlFilterBase
& rFilter
, const OUString
& sFragment
, const OUString
& sType
)
1406 uno::Sequence
< uno::Sequence
< uno::Any
> > xRelListTemp
;
1407 sal_Int32 counter
= 0;
1409 core::RelationsRef xRels
= rFilter
.importRelations( sFragment
);
1412 core::RelationsRef xImageRels
= xRels
->getRelationsFromTypeFromOfficeDoc( sType
);
1415 xRelListTemp
.realloc( xImageRels
->size() );
1416 for( ::std::map
< OUString
, core::Relation
>::const_iterator aIt
= xImageRels
->begin(), aEnd
= xImageRels
->end(); aIt
!= aEnd
; ++aIt
)
1418 uno::Sequence
< uno::Any
> diagramRelTuple (3);
1419 // [0] => RID, [1] => InputStream [2] => extension
1420 OUString sRelId
= aIt
->second
.maId
;
1422 diagramRelTuple
[0] = uno::makeAny ( sRelId
);
1423 OUString sTarget
= xImageRels
->getFragmentPathFromRelId( sRelId
);
1425 uno::Reference
< io::XInputStream
> xImageInputStrm( rFilter
.openInputStream( sTarget
), uno::UNO_SET_THROW
);
1426 StreamDataSequence dataSeq
;
1427 if ( rFilter
.importBinaryData( dataSeq
, sTarget
) )
1429 diagramRelTuple
[1] = uno::makeAny( dataSeq
);
1432 diagramRelTuple
[2] = uno::makeAny( sTarget
.copy( sTarget
.lastIndexOf(".") ) );
1434 xRelListTemp
[counter
] = diagramRelTuple
;
1437 xRelListTemp
.realloc(counter
);
1441 return xRelListTemp
;
1446 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */