| /************************************************************** |
| * |
| * 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:; |
| } |
| } |
| |
| // ============================================================================ |
| |
| } } |