1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir #include "oox/drawingml/chart/chartdrawingfragment.hxx" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #include "oox/core/xmlfilterbase.hxx" 31*cdf0e10cSrcweir #include "oox/drawingml/connectorshapecontext.hxx" 32*cdf0e10cSrcweir #include "oox/drawingml/graphicshapecontext.hxx" 33*cdf0e10cSrcweir #include "oox/drawingml/shapecontext.hxx" 34*cdf0e10cSrcweir #include "oox/drawingml/shapegroupcontext.hxx" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir namespace oox { 37*cdf0e10cSrcweir namespace drawingml { 38*cdf0e10cSrcweir namespace chart { 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir // ============================================================================ 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir using namespace ::com::sun::star::awt; 43*cdf0e10cSrcweir using namespace ::com::sun::star::drawing; 44*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 45*cdf0e10cSrcweir using namespace ::oox::core; 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir using ::rtl::OUString; 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir // ============================================================================ 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir ShapeAnchor::ShapeAnchor( bool bRelSize ) : 52*cdf0e10cSrcweir mbRelSize( bRelSize ) 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir } 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir void ShapeAnchor::importExt( const AttributeList& rAttribs ) 57*cdf0e10cSrcweir { 58*cdf0e10cSrcweir OSL_ENSURE( !mbRelSize, "ShapeAnchor::importExt - unexpected 'cdr:ext' element" ); 59*cdf0e10cSrcweir maSize.Width = rAttribs.getHyper( XML_cx, 0 ); 60*cdf0e10cSrcweir maSize.Height = rAttribs.getHyper( XML_cy, 0 ); 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir void ShapeAnchor::setPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue ) 64*cdf0e10cSrcweir { 65*cdf0e10cSrcweir AnchorPosModel* pAnchorPos = 0; 66*cdf0e10cSrcweir switch( nParentContext ) 67*cdf0e10cSrcweir { 68*cdf0e10cSrcweir case CDR_TOKEN( from ): 69*cdf0e10cSrcweir pAnchorPos = &maFrom; 70*cdf0e10cSrcweir break; 71*cdf0e10cSrcweir case CDR_TOKEN( to ): 72*cdf0e10cSrcweir OSL_ENSURE( mbRelSize, "ShapeAnchor::setPos - unexpected 'cdr:to' element" ); 73*cdf0e10cSrcweir pAnchorPos = &maTo; 74*cdf0e10cSrcweir break; 75*cdf0e10cSrcweir default: 76*cdf0e10cSrcweir OSL_ENSURE( false, "ShapeAnchor::setPos - unexpected parent element" ); 77*cdf0e10cSrcweir } 78*cdf0e10cSrcweir if( pAnchorPos ) switch( nElement ) 79*cdf0e10cSrcweir { 80*cdf0e10cSrcweir case CDR_TOKEN( x ): pAnchorPos->mfX = rValue.toDouble(); break; 81*cdf0e10cSrcweir case CDR_TOKEN( y ): pAnchorPos->mfY = rValue.toDouble(); break; 82*cdf0e10cSrcweir default: OSL_ENSURE( false, "ShapeAnchor::setPos - unexpected element" ); 83*cdf0e10cSrcweir } 84*cdf0e10cSrcweir } 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir EmuRectangle ShapeAnchor::calcAnchorRectEmu( const EmuRectangle& rChartRect ) const 87*cdf0e10cSrcweir { 88*cdf0e10cSrcweir EmuRectangle aAnchorRect( -1, -1, -1, -1 ); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid from position" ); 91*cdf0e10cSrcweir OSL_ENSURE( mbRelSize ? maTo.isValid() : maSize.isValid(), "ShapeAnchor::calcAnchorRectEmu - invalid to/size" ); 92*cdf0e10cSrcweir if( maFrom.isValid() && (mbRelSize ? maTo.isValid() : maSize.isValid()) ) 93*cdf0e10cSrcweir { 94*cdf0e10cSrcweir // calculate shape position 95*cdf0e10cSrcweir aAnchorRect.X = static_cast< sal_Int64 >( maFrom.mfX * rChartRect.Width + 0.5 ); 96*cdf0e10cSrcweir aAnchorRect.Y = static_cast< sal_Int64 >( maFrom.mfY * rChartRect.Height + 0.5 ); 97*cdf0e10cSrcweir 98*cdf0e10cSrcweir // calculate shape size 99*cdf0e10cSrcweir if( mbRelSize ) 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir aAnchorRect.Width = static_cast< sal_Int64 >( maTo.mfX * rChartRect.Width + 0.5 ) - aAnchorRect.X; 102*cdf0e10cSrcweir if( aAnchorRect.Width < 0 ) 103*cdf0e10cSrcweir { 104*cdf0e10cSrcweir aAnchorRect.X += aAnchorRect.Width; 105*cdf0e10cSrcweir aAnchorRect.Width *= -1; 106*cdf0e10cSrcweir } 107*cdf0e10cSrcweir aAnchorRect.Height = static_cast< sal_Int64 >( maTo.mfY * rChartRect.Height + 0.5 ) - aAnchorRect.Y; 108*cdf0e10cSrcweir if( aAnchorRect.Height < 0 ) 109*cdf0e10cSrcweir { 110*cdf0e10cSrcweir aAnchorRect.Y += aAnchorRect.Height; 111*cdf0e10cSrcweir aAnchorRect.Height *= -1; 112*cdf0e10cSrcweir } 113*cdf0e10cSrcweir } 114*cdf0e10cSrcweir else 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir aAnchorRect.setSize( maSize ); 117*cdf0e10cSrcweir } 118*cdf0e10cSrcweir } 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir return aAnchorRect; 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir // ============================================================================ 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir ChartDrawingFragment::ChartDrawingFragment( XmlFilterBase& rFilter, 125*cdf0e10cSrcweir const OUString& rFragmentPath, const Reference< XShapes >& rxDrawPage, 126*cdf0e10cSrcweir const Size& rChartSize, const Point& rShapesOffset, bool bOleSupport ) : 127*cdf0e10cSrcweir FragmentHandler2( rFilter, rFragmentPath ), 128*cdf0e10cSrcweir mxDrawPage( rxDrawPage ), 129*cdf0e10cSrcweir mbOleSupport( bOleSupport ) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir maChartRectEmu.X = convertHmmToEmu( rShapesOffset.X ); 132*cdf0e10cSrcweir maChartRectEmu.Y = convertHmmToEmu( rShapesOffset.Y ); 133*cdf0e10cSrcweir maChartRectEmu.Width = convertHmmToEmu( rChartSize.Width ); 134*cdf0e10cSrcweir maChartRectEmu.Height = convertHmmToEmu( rChartSize.Height ); 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir ChartDrawingFragment::~ChartDrawingFragment() 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir 141*cdf0e10cSrcweir ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) 142*cdf0e10cSrcweir { 143*cdf0e10cSrcweir switch( getCurrentElement() ) 144*cdf0e10cSrcweir { 145*cdf0e10cSrcweir case XML_ROOT_CONTEXT: 146*cdf0e10cSrcweir if( nElement == C_TOKEN( userShapes ) ) return this; 147*cdf0e10cSrcweir break; 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir case C_TOKEN( userShapes ): 150*cdf0e10cSrcweir switch( nElement ) 151*cdf0e10cSrcweir { 152*cdf0e10cSrcweir case CDR_TOKEN( absSizeAnchor ): 153*cdf0e10cSrcweir mxAnchor.reset( new ShapeAnchor( false ) ); 154*cdf0e10cSrcweir return this; 155*cdf0e10cSrcweir case CDR_TOKEN( relSizeAnchor ): 156*cdf0e10cSrcweir mxAnchor.reset( new ShapeAnchor( true ) ); 157*cdf0e10cSrcweir return this; 158*cdf0e10cSrcweir } 159*cdf0e10cSrcweir break; 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir case CDR_TOKEN( absSizeAnchor ): 162*cdf0e10cSrcweir case CDR_TOKEN( relSizeAnchor ): 163*cdf0e10cSrcweir switch( nElement ) 164*cdf0e10cSrcweir { 165*cdf0e10cSrcweir case CDR_TOKEN( sp ): 166*cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.CustomShape" ) ); 167*cdf0e10cSrcweir return new ShapeContext( *this, ShapePtr(), mxShape ); 168*cdf0e10cSrcweir case CDR_TOKEN( cxnSp ): 169*cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.ConnectorShape" ) ); 170*cdf0e10cSrcweir return new ConnectorShapeContext( *this, ShapePtr(), mxShape ); 171*cdf0e10cSrcweir case CDR_TOKEN( pic ): 172*cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ); 173*cdf0e10cSrcweir return new GraphicShapeContext( *this, ShapePtr(), mxShape ); 174*cdf0e10cSrcweir case CDR_TOKEN( graphicFrame ): 175*cdf0e10cSrcweir if( !mbOleSupport ) 176*cdf0e10cSrcweir return 0; 177*cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ); 178*cdf0e10cSrcweir return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape, true ); 179*cdf0e10cSrcweir case CDR_TOKEN( grpSp ): 180*cdf0e10cSrcweir mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) ); 181*cdf0e10cSrcweir return new ShapeGroupContext( *this, ShapePtr(), mxShape ); 182*cdf0e10cSrcweir 183*cdf0e10cSrcweir case CDR_TOKEN( from ): 184*cdf0e10cSrcweir case CDR_TOKEN( to ): 185*cdf0e10cSrcweir return this; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir case CDR_TOKEN( ext ): 188*cdf0e10cSrcweir if( mxAnchor.get() ) mxAnchor->importExt( rAttribs ); 189*cdf0e10cSrcweir return 0; 190*cdf0e10cSrcweir } 191*cdf0e10cSrcweir break; 192*cdf0e10cSrcweir 193*cdf0e10cSrcweir case CDR_TOKEN( from ): 194*cdf0e10cSrcweir case CDR_TOKEN( to ): 195*cdf0e10cSrcweir switch( nElement ) 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir case CDR_TOKEN( x ): 198*cdf0e10cSrcweir case CDR_TOKEN( y ): 199*cdf0e10cSrcweir return this; // collect value in onEndElement() 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir break; 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir return 0; 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir void ChartDrawingFragment::onCharacters( const OUString& rChars ) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir if( isCurrentElement( CDR_TOKEN( x ), CDR_TOKEN( y ) ) && mxAnchor.get() ) 209*cdf0e10cSrcweir mxAnchor->setPos( getCurrentElement(), getParentElement(), rChars ); 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir void ChartDrawingFragment::onEndElement() 213*cdf0e10cSrcweir { 214*cdf0e10cSrcweir if( isCurrentElement( CDR_TOKEN( absSizeAnchor ), CDR_TOKEN( relSizeAnchor ) ) ) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() ) 217*cdf0e10cSrcweir { 218*cdf0e10cSrcweir EmuRectangle aShapeRectEmu = mxAnchor->calcAnchorRectEmu( maChartRectEmu ); 219*cdf0e10cSrcweir if( (aShapeRectEmu.X >= 0) && (aShapeRectEmu.Y >= 0) && (aShapeRectEmu.Width >= 0) && (aShapeRectEmu.Height >= 0) ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir // TODO: DrawingML implementation expects 32-bit coordinates for EMU rectangles (change that to EmuRectangle) 222*cdf0e10cSrcweir Rectangle aShapeRectEmu32( 223*cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.X, 0, SAL_MAX_INT32 ), 224*cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Y, 0, SAL_MAX_INT32 ), 225*cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Width, 0, SAL_MAX_INT32 ), 226*cdf0e10cSrcweir getLimitedValue< sal_Int32, sal_Int64 >( aShapeRectEmu.Height, 0, SAL_MAX_INT32 ) ); 227*cdf0e10cSrcweir mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aShapeRectEmu32 ); 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir mxShape.reset(); 231*cdf0e10cSrcweir mxAnchor.reset(); 232*cdf0e10cSrcweir } 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir // ============================================================================ 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir } // namespace chart 238*cdf0e10cSrcweir } // namespace drawingml 239*cdf0e10cSrcweir } // namespace oox 240