blob: a1c76d36ad5255202457a712b737e2757886f9c9 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "oox/drawingml/shape.hxx"
#include "oox/drawingml/customshapeproperties.hxx"
#include "oox/drawingml/theme.hxx"
#include "oox/drawingml/fillproperties.hxx"
#include "oox/drawingml/lineproperties.hxx"
#include "oox/drawingml/shapepropertymap.hxx"
#include "oox/drawingml/textbody.hxx"
#include "oox/drawingml/table/tableproperties.hxx"
#include "oox/drawingml/chart/chartconverter.hxx"
#include "oox/drawingml/chart/chartspacefragment.hxx"
#include "oox/drawingml/chart/chartspacemodel.hxx"
#include "oox/vml/vmldrawing.hxx"
#include "oox/vml/vmlshape.hxx"
#include "oox/vml/vmlshapecontainer.hxx"
#include "oox/core/xmlfilterbase.hxx"
#include "oox/helper/graphichelper.hxx"
#include "oox/helper/propertyset.hxx"
#include <tools/solar.h> // for the F_PI180 define
#include <com/sun/star/graphic/XGraphic.hpp>
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/drawing/HomogenMatrix3.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <com/sun/star/document/XActionLockable.hpp>
using rtl::OUString;
using namespace ::oox::core;
using namespace ::com::sun::star;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::drawing;
namespace oox { namespace drawingml {
// ============================================================================
Shape::Shape( const sal_Char* pServiceName )
: mpLinePropertiesPtr( new LineProperties )
, mpFillPropertiesPtr( new FillProperties )
, mpGraphicPropertiesPtr( new GraphicProperties )
, mpCustomShapePropertiesPtr( new CustomShapeProperties )
, mpMasterTextListStyle( new TextListStyle )
, mnSubType( 0 )
, mnSubTypeIndex( -1 )
, meFrameType( FRAMETYPE_GENERIC )
, mnRotation( 0 )
, mbFlipH( false )
, mbFlipV( false )
, mbHidden( false )
{
if ( pServiceName )
msServiceName = OUString::createFromAscii( pServiceName );
setDefaults();
}
Shape::~Shape()
{
}
table::TablePropertiesPtr Shape::getTableProperties()
{
if ( !mpTablePropertiesPtr.get() )
mpTablePropertiesPtr.reset( new table::TableProperties() );
return mpTablePropertiesPtr;
}
void Shape::setDefaults()
{
maShapeProperties[ PROP_TextAutoGrowHeight ] <<= false;
maShapeProperties[ PROP_TextWordWrap ] <<= true;
maShapeProperties[ PROP_TextLeftDistance ] <<= static_cast< sal_Int32 >( 250 );
maShapeProperties[ PROP_TextUpperDistance ] <<= static_cast< sal_Int32 >( 125 );
maShapeProperties[ PROP_TextRightDistance ] <<= static_cast< sal_Int32 >( 250 );
maShapeProperties[ PROP_TextLowerDistance ] <<= static_cast< sal_Int32 >( 125 );
maShapeProperties[ PROP_CharHeight ] <<= static_cast< float >( 18.0 );
}
::oox::vml::OleObjectInfo& Shape::setOleObjectType()
{
OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" );
meFrameType = FRAMETYPE_OLEOBJECT;
mxOleObjectInfo.reset( new ::oox::vml::OleObjectInfo( true ) );
return *mxOleObjectInfo;
}
ChartShapeInfo& Shape::setChartType( bool bEmbedShapes )
{
OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" );
meFrameType = FRAMETYPE_CHART;
msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" );
mxChartShapeInfo.reset( new ChartShapeInfo( bEmbedShapes ) );
return *mxChartShapeInfo;
}
void Shape::setDiagramType()
{
OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" );
meFrameType = FRAMETYPE_DIAGRAM;
msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" );
mnSubType = 0;
}
void Shape::setTableType()
{
OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" );
meFrameType = FRAMETYPE_TABLE;
msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.TableShape" );
mnSubType = 0;
}
void Shape::setServiceName( const sal_Char* pServiceName )
{
if ( pServiceName )
msServiceName = OUString::createFromAscii( pServiceName );
}
const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const
{
ShapeStyleRefMap::const_iterator aIt = maShapeStyleRefs.find( nRefType );
return (aIt == maShapeStyleRefs.end()) ? 0 : &aIt->second;
}
void Shape::addShape(
::oox::core::XmlFilterBase& rFilterBase,
const Theme* pTheme,
const Reference< XShapes >& rxShapes,
const awt::Rectangle* pShapeRect,
ShapeIdMap* pShapeMap )
{
try
{
rtl::OUString sServiceName( msServiceName );
if( sServiceName.getLength() )
{
Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, pShapeRect, sal_False ) );
if( pShapeMap && msId.getLength() )
{
(*pShapeMap)[ msId ] = shared_from_this();
}
// if this is a group shape, we have to add also each child shape
Reference< XShapes > xShapes( xShape, UNO_QUERY );
if ( xShapes.is() )
addChildren( rFilterBase, *this, pTheme, xShapes, pShapeRect ? *pShapeRect : awt::Rectangle( maPosition.X, maPosition.Y, maSize.Width, maSize.Height ), pShapeMap );
}
}
catch( const Exception& )
{
}
}
void Shape::applyShapeReference( const Shape& rReferencedShape )
{
if ( rReferencedShape.mpTextBody.get() )
mpTextBody = TextBodyPtr( new TextBody( *rReferencedShape.mpTextBody.get() ) );
maShapeProperties = rReferencedShape.maShapeProperties;
mpLinePropertiesPtr = LinePropertiesPtr( new LineProperties( *rReferencedShape.mpLinePropertiesPtr.get() ) );
mpFillPropertiesPtr = FillPropertiesPtr( new FillProperties( *rReferencedShape.mpFillPropertiesPtr.get() ) );
mpCustomShapePropertiesPtr = CustomShapePropertiesPtr( new CustomShapeProperties( *rReferencedShape.mpCustomShapePropertiesPtr.get() ) );
mpTablePropertiesPtr = table::TablePropertiesPtr( rReferencedShape.mpTablePropertiesPtr.get() ? new table::TableProperties( *rReferencedShape.mpTablePropertiesPtr.get() ) : NULL );
mpMasterTextListStyle = TextListStylePtr( new TextListStyle( *rReferencedShape.mpMasterTextListStyle.get() ) );
maShapeStyleRefs = rReferencedShape.maShapeStyleRefs;
maSize = rReferencedShape.maSize;
maPosition = rReferencedShape.maPosition;
mnRotation = rReferencedShape.mnRotation;
mbFlipH = rReferencedShape.mbFlipH;
mbFlipV = rReferencedShape.mbFlipV;
mbHidden = rReferencedShape.mbHidden;
}
// for group shapes, the following method is also adding each child
void Shape::addChildren(
XmlFilterBase& rFilterBase,
Shape& rMaster,
const Theme* pTheme,
const Reference< XShapes >& rxShapes,
const awt::Rectangle& rClientRect,
ShapeIdMap* pShapeMap )
{
// first the global child union needs to be calculated
sal_Int32 nGlobalLeft = SAL_MAX_INT32;
sal_Int32 nGlobalRight = SAL_MIN_INT32;
sal_Int32 nGlobalTop = SAL_MAX_INT32;
sal_Int32 nGlobalBottom= SAL_MIN_INT32;
std::vector< ShapePtr >::iterator aIter( rMaster.maChildren.begin() );
while( aIter != rMaster.maChildren.end() )
{
sal_Int32 l = (*aIter)->maPosition.X;
sal_Int32 t = (*aIter)->maPosition.Y;
sal_Int32 r = l + (*aIter)->maSize.Width;
sal_Int32 b = t + (*aIter)->maSize.Height;
if ( nGlobalLeft > l )
nGlobalLeft = l;
if ( nGlobalRight < r )
nGlobalRight = r;
if ( nGlobalTop > t )
nGlobalTop = t;
if ( nGlobalBottom < b )
nGlobalBottom = b;
aIter++;
}
aIter = rMaster.maChildren.begin();
while( aIter != rMaster.maChildren.end() )
{
awt::Rectangle aShapeRect;
awt::Rectangle* pShapeRect = 0;
if ( ( nGlobalLeft != SAL_MAX_INT32 ) && ( nGlobalRight != SAL_MIN_INT32 ) && ( nGlobalTop != SAL_MAX_INT32 ) && ( nGlobalBottom != SAL_MIN_INT32 ) )
{
sal_Int32 nGlobalWidth = nGlobalRight - nGlobalLeft;
sal_Int32 nGlobalHeight = nGlobalBottom - nGlobalTop;
if ( nGlobalWidth && nGlobalHeight )
{
double fWidth = (*aIter)->maSize.Width;
double fHeight= (*aIter)->maSize.Height;
double fXScale = (double)rClientRect.Width / (double)nGlobalWidth;
double fYScale = (double)rClientRect.Height / (double)nGlobalHeight;
aShapeRect.X = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.X - nGlobalLeft ) * fXScale ) + rClientRect.X );
aShapeRect.Y = static_cast< sal_Int32 >( ( ( (*aIter)->maPosition.Y - nGlobalTop ) * fYScale ) + rClientRect.Y );
fWidth *= fXScale;
fHeight *= fYScale;
aShapeRect.Width = static_cast< sal_Int32 >( fWidth );
aShapeRect.Height = static_cast< sal_Int32 >( fHeight );
pShapeRect = &aShapeRect;
}
}
(*aIter++)->addShape( rFilterBase, pTheme, rxShapes, pShapeRect, pShapeMap );
}
}
Reference< XShape > Shape::createAndInsert(
::oox::core::XmlFilterBase& rFilterBase,
const rtl::OUString& rServiceName,
const Theme* pTheme,
const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
const awt::Rectangle* pShapeRect,
sal_Bool bClearText )
{
awt::Size aSize( pShapeRect ? awt::Size( pShapeRect->Width, pShapeRect->Height ) : maSize );
awt::Point aPosition( pShapeRect ? awt::Point( pShapeRect->X, pShapeRect->Y ) : maPosition );
awt::Rectangle aShapeRectHmm( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 );
OUString aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm );
sal_Bool bIsCustomShape = aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShape" ) );
basegfx::B2DHomMatrix aTransformation;
if( aSize.Width != 1 || aSize.Height != 1)
{
// take care there are no zeros used by error
aTransformation.scale(
aSize.Width ? aSize.Width / 360.0 : 1.0,
aSize.Height ? aSize.Height / 360.0 : 1.0 );
}
if( mbFlipH || mbFlipV || mnRotation != 0)
{
// calculate object's center
basegfx::B2DPoint aCenter(0.5, 0.5);
aCenter *= aTransformation;
// center object at origin
aTransformation.translate( -aCenter.getX(), -aCenter.getY() );
if( !bIsCustomShape && ( mbFlipH || mbFlipV ) )
{
// mirror around object's center
aTransformation.scale( mbFlipH ? -1.0 : 1.0, mbFlipV ? -1.0 : 1.0 );
}
if( mnRotation != 0 )
{
// rotate around object's center
aTransformation.rotate( F_PI180 * ( (double)mnRotation / 60000.0 ) );
}
// move object back from center
aTransformation.translate( aCenter.getX(), aCenter.getY() );
}
if( aPosition.X != 0 || aPosition.Y != 0)
{
// if global position is used, add it to transformation
aTransformation.translate( aPosition.X / 360.0, aPosition.Y / 360.0 );
}
// special for lineshape
if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.LineShape" ) )
{
::basegfx::B2DPolygon aPoly;
aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
aPoly.transform( aTransformation );
// now creating the corresponding PolyPolygon
sal_Int32 i, nNumPoints = aPoly.count();
uno::Sequence< awt::Point > aPointSequence( nNumPoints );
awt::Point* pPoints = aPointSequence.getArray();
for( i = 0; i < nNumPoints; ++i )
{
const ::basegfx::B2DPoint aPoint( aPoly.getB2DPoint( i ) );
pPoints[ i ] = awt::Point( static_cast< sal_Int32 >( aPoint.getX() ), static_cast< sal_Int32 >( aPoint.getY() ) );
}
uno::Sequence< uno::Sequence< awt::Point > > aPolyPolySequence( 1 );
aPolyPolySequence.getArray()[ 0 ] = aPointSequence;
maShapeProperties[ PROP_PolyPolygon ] <<= aPolyPolySequence;
}
else if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.ConnectorShape" ) )
{
::basegfx::B2DPolygon aPoly;
aPoly.insert( 0, ::basegfx::B2DPoint( 0, 0 ) );
aPoly.insert( 1, ::basegfx::B2DPoint( maSize.Width ? 1 : 0, maSize.Height ? 1 : 0 ) );
aPoly.transform( aTransformation );
basegfx::B2DPoint aStartPosition( aPoly.getB2DPoint( 0 ) );
basegfx::B2DPoint aEndPosition( aPoly.getB2DPoint( 1 ) );
awt::Point aAWTStartPosition( static_cast< sal_Int32 >( aStartPosition.getX() ), static_cast< sal_Int32 >( aStartPosition.getY() ) );
awt::Point aAWTEndPosition( static_cast< sal_Int32 >( aEndPosition.getX() ), static_cast< sal_Int32 >( aEndPosition.getY() ) );
maShapeProperties[ PROP_StartPosition ] <<= aAWTStartPosition;
maShapeProperties[ PROP_EndPosition ] <<= aAWTEndPosition;
}
else
{
// now set transformation for this object
HomogenMatrix3 aMatrix;
aMatrix.Line1.Column1 = aTransformation.get(0,0);
aMatrix.Line1.Column2 = aTransformation.get(0,1);
aMatrix.Line1.Column3 = aTransformation.get(0,2);
aMatrix.Line2.Column1 = aTransformation.get(1,0);
aMatrix.Line2.Column2 = aTransformation.get(1,1);
aMatrix.Line2.Column3 = aTransformation.get(1,2);
aMatrix.Line3.Column1 = aTransformation.get(2,0);
aMatrix.Line3.Column2 = aTransformation.get(2,1);
aMatrix.Line3.Column3 = aTransformation.get(2,2);
maShapeProperties[ PROP_Transformation ] <<= aMatrix;
}
Reference< lang::XMultiServiceFactory > xServiceFact( rFilterBase.getModel(), UNO_QUERY_THROW );
if ( !mxShape.is() )
mxShape = Reference< drawing::XShape >( xServiceFact->createInstance( aServiceName ), UNO_QUERY_THROW );
Reference< XPropertySet > xSet( mxShape, UNO_QUERY );
if( mxShape.is() && xSet.is() )
{
if( msName.getLength() )
{
Reference< container::XNamed > xNamed( mxShape, UNO_QUERY );
if( xNamed.is() )
xNamed->setName( msName );
}
rxShapes->add( mxShape );
if ( mbHidden )
{
const OUString sHidden( CREATE_OUSTRING( "Visible" ) );
xSet->setPropertyValue( sHidden, Any( !mbHidden ) );
}
Reference< document::XActionLockable > xLockable( mxShape, UNO_QUERY );
if( xLockable.is() )
xLockable->addActionLock();
// sj: removing default text of placeholder objects such as SlideNumberShape or HeaderShape
if ( bClearText )
{
uno::Reference< text::XText > xText( mxShape, uno::UNO_QUERY );
if ( xText.is() )
{
OUString aEmpty;
xText->setString( aEmpty );
}
}
const GraphicHelper& rGraphicHelper = rFilterBase.getGraphicHelper();
LineProperties aLineProperties;
aLineProperties.maLineFill.moFillType = XML_noFill;
sal_Int32 nLinePhClr = -1;
FillProperties aFillProperties;
aFillProperties.moFillType = XML_noFill;
sal_Int32 nFillPhClr = -1;
if( pTheme )
{
if( const ShapeStyleRef* pLineRef = getShapeStyleRef( XML_lnRef ) )
{
if( const LineProperties* pLineProps = pTheme->getLineStyle( pLineRef->mnThemedIdx ) )
aLineProperties.assignUsed( *pLineProps );
nLinePhClr = pLineRef->maPhClr.getColor( rGraphicHelper );
}
if( const ShapeStyleRef* pFillRef = getShapeStyleRef( XML_fillRef ) )
{
if( const FillProperties* pFillProps = pTheme->getFillStyle( pFillRef->mnThemedIdx ) )
aFillProperties.assignUsed( *pFillProps );
nFillPhClr = pFillRef->maPhClr.getColor( rGraphicHelper );
}
// if( const ShapeStyleRef* pEffectRef = getShapeStyleRef( XML_fillRef ) )
// {
// if( const EffectProperties* pEffectProps = pTheme->getEffectStyle( pEffectRef->mnThemedIdx ) )
// aEffectProperties.assignUsed( *pEffectProps );
// nEffectPhClr = pEffectRef->maPhClr.getColor( rGraphicHelper );
// }
}
aLineProperties.assignUsed( getLineProperties() );
aFillProperties.assignUsed( getFillProperties() );
ShapePropertyMap aShapeProps( rFilterBase.getModelObjectHelper() );
// add properties from textbody to shape properties
if( mpTextBody.get() )
aShapeProps.assignUsed( mpTextBody->getTextProperties().maPropertyMap );
// applying properties
aShapeProps.assignUsed( getShapeProperties() );
if ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.GraphicObjectShape" ) )
mpGraphicPropertiesPtr->pushToPropMap( aShapeProps, rGraphicHelper );
if ( mpTablePropertiesPtr.get() && ( aServiceName == OUString::createFromAscii( "com.sun.star.drawing.TableShape" ) ) )
mpTablePropertiesPtr->pushToPropSet( rFilterBase, xSet, mpMasterTextListStyle );
aFillProperties.pushToPropMap( aShapeProps, rGraphicHelper, mnRotation, nFillPhClr );
aLineProperties.pushToPropMap( aShapeProps, rGraphicHelper, nLinePhClr );
// applying autogrowheight property before setting shape size, because
// the shape size might be changed if currently autogrowheight is true
// we must also check that the PropertySet supports the property.
Reference< XPropertySetInfo > xSetInfo( xSet->getPropertySetInfo() );
const OUString& rPropName = PropertyMap::getPropertyName( PROP_TextAutoGrowHeight );
if( xSetInfo.is() && xSetInfo->hasPropertyByName( rPropName ) )
if( aShapeProps.hasProperty( PROP_TextAutoGrowHeight ) )
xSet->setPropertyValue( rPropName, Any( false ) );
// do not set properties at a group shape (this causes assertions from svx)
if( aServiceName != OUString::createFromAscii( "com.sun.star.drawing.GroupShape" ) )
PropertySet( xSet ).setProperties( aShapeProps );
if( bIsCustomShape )
{
if ( mbFlipH )
mpCustomShapePropertiesPtr->setMirroredX( sal_True );
if ( mbFlipV )
mpCustomShapePropertiesPtr->setMirroredY( sal_True );
// #119920# Handle missing text rotation
if(getTextBody())
{
const sal_Int32 nTextRotation(getTextBody()->getTextProperties().moRotation.get(0));
if(nTextRotation)
{
mpCustomShapePropertiesPtr->setTextRotation((nTextRotation * -1) / 60000);
}
}
mpCustomShapePropertiesPtr->pushToPropSet( rFilterBase, xSet, mxShape );
}
// in some cases, we don't have any text body.
if( getTextBody() )
{
Reference < XText > xText( mxShape, UNO_QUERY );
if ( xText.is() ) // not every shape is supporting an XText interface (e.g. GroupShape)
{
TextCharacterProperties aCharStyleProperties;
if( const ShapeStyleRef* pFontRef = getShapeStyleRef( XML_fontRef ) )
{
if( pTheme )
if( const TextCharacterProperties* pCharProps = pTheme->getFontStyle( pFontRef->mnThemedIdx ) )
aCharStyleProperties.assignUsed( *pCharProps );
aCharStyleProperties.maCharColor.assignIfUsed( pFontRef->maPhClr );
}
Reference < XTextCursor > xAt = xText->createTextCursor();
getTextBody()->insertAt( rFilterBase, xText, xAt, aCharStyleProperties, mpMasterTextListStyle );
}
}
if( xLockable.is() )
xLockable->removeActionLock();
}
if( mxShape.is() )
finalizeXShape( rFilterBase, rxShapes );
return mxShape;
}
// the properties of rSource which are not part of rDest are being put into rDest
void addMissingProperties( const PropertyMap& rSource, PropertyMap& rDest )
{
PropertyMap::const_iterator aSourceIter( rSource.begin() );
while( aSourceIter != rSource.end() )
{
if ( rDest.find( (*aSourceIter ).first ) == rDest.end() )
rDest[ (*aSourceIter).first ] <<= (*aSourceIter).second;
aSourceIter++;
}
}
void Shape::setTextBody(const TextBodyPtr & pTextBody)
{
mpTextBody = pTextBody;
}
TextBodyPtr Shape::getTextBody()
{
return mpTextBody;
}
void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle )
{
mpMasterTextListStyle = pMasterTextListStyle;
}
OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const Rectangle& rShapeRect )
{
OUString aServiceName = rServiceName;
switch( meFrameType )
{
case FRAMETYPE_OLEOBJECT:
{
Size aOleSize( rShapeRect.Width, rShapeRect.Height );
if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) )
aServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" );
// get the path to the representation graphic
OUString aGraphicPath;
if( mxOleObjectInfo->maShapeId.getLength() > 0 )
if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() )
if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) )
aGraphicPath = pVmlShape->getGraphicPath();
// import and store the graphic
if( aGraphicPath.getLength() > 0 )
{
Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath );
if( xGraphic.is() )
maShapeProperties[ PROP_Graphic ] <<= xGraphic;
}
}
break;
default:;
}
return aServiceName;
}
void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes )
{
switch( meFrameType )
{
case FRAMETYPE_CHART:
{
OSL_ENSURE( mxChartShapeInfo->maFragmentPath.getLength() > 0, "Shape::finalizeXShape - missing chart fragment" );
if( mxShape.is() && (mxChartShapeInfo->maFragmentPath.getLength() > 0) ) try
{
// set the chart2 OLE class ID at the OLE shape
PropertySet aShapeProp( mxShape );
aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) );
// get the XModel interface of the embedded object from the OLE shape
Reference< frame::XModel > xDocModel;
aShapeProp.getProperty( xDocModel, PROP_Model );
Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW );
// load the chart data from the XML fragment
chart::ChartSpaceModel aModel;
rFilter.importFragment( new chart::ChartSpaceFragment( rFilter, mxChartShapeInfo->maFragmentPath, aModel ) );
// convert imported chart model to chart document
Reference< drawing::XShapes > xExternalPage;
if( !mxChartShapeInfo->mbEmbedShapes )
xExternalPage = rxShapes;
rFilter.getChartConverter().convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() );
}
catch( Exception& )
{
}
}
break;
default:;
}
}
// ============================================================================
} }