summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2008-03-05 17:58:39 +0000
committerKurt Zenker <kz@openoffice.org>2008-03-05 17:58:39 +0000
commit72dbf5ebc54cf484d9d95c721dbb66ad526192ea (patch)
tree0ec69076cfe38b0f77febbe6cb52ac0be2e31a51 /oox
parent6dfc9ffdfd97478a208e00813377380ff90d299f (diff)
INTEGRATION: CWS xmlfilter03_DEV300 (1.1.2); FILE ADDED
2008/02/11 10:28:08 dr 1.1.2.10: comments 2008/02/08 11:49:44 dr 1.1.2.9: correct shape positioning in sheet 2008/02/06 15:46:14 dr 1.1.2.8: shape positions in EMUs 2008/02/06 10:11:48 dr 1.1.2.7: handle all shape types 2008/02/05 14:08:07 dr 1.1.2.6: oox::core::ContextHandler2 and oox::core::FragmentHandler2 for convenience 2008/02/04 13:33:19 dr 1.1.2.5: rework of fragment handler/context handler base classes 2008/02/01 10:42:46 dr 1.1.2.4: typo 2008/02/01 09:55:36 dr 1.1.2.3: addShape() code cleanup, started xlsx drawing import 2008/01/28 09:48:48 dr 1.1.2.2: unit converter with unit enum; xdr:pos and xdr:ext use attributes, not child elements 2008/01/25 14:24:18 dr 1.1.2.1: drawing import: anchors
Diffstat (limited to 'oox')
-rw-r--r--oox/source/xls/drawingfragment.cxx460
1 files changed, 460 insertions, 0 deletions
diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx
new file mode 100644
index 000000000000..496bc9214c8d
--- /dev/null
+++ b/oox/source/xls/drawingfragment.cxx
@@ -0,0 +1,460 @@
+/*************************************************************************
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: drawingfragment.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: kz $ $Date: 2008-03-05 18:58:39 $
+ *
+ * The Contents of this file are made available subject to
+ * the terms of GNU Lesser General Public License Version 2.1.
+ *
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2005 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ ************************************************************************/
+
+#include "oox/xls/drawingfragment.hxx"
+#include <com/sun/star/awt/Point.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include "oox/helper/attributelist.hxx"
+#include "oox/drawingml/connectorshapecontext.hxx"
+#include "oox/drawingml/graphicshapecontext.hxx"
+#include "oox/drawingml/shapecontext.hxx"
+#include "oox/drawingml/shapegroupcontext.hxx"
+#include "oox/xls/themebuffer.hxx"
+#include "oox/xls/unitconverter.hxx"
+
+using ::rtl::OUString;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::awt::Point;
+using ::com::sun::star::awt::Size;
+using ::com::sun::star::awt::Rectangle;
+using ::com::sun::star::drawing::XDrawPageSupplier;
+using ::com::sun::star::table::CellAddress;
+using ::oox::drawingml::ConnectorShapeContext;
+using ::oox::drawingml::GraphicalObjectFrameContext;
+using ::oox::drawingml::GraphicShapeContext;
+using ::oox::drawingml::Shape;
+using ::oox::drawingml::ShapePtr;
+using ::oox::drawingml::ShapeContext;
+using ::oox::drawingml::ShapeGroupContext;
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+OoxAnchorPosition::OoxAnchorPosition() :
+ mnX( -1 ),
+ mnY( -1 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxAnchorSize::OoxAnchorSize() :
+ mnWidth( -1 ),
+ mnHeight( -1 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxAnchorCell::OoxAnchorCell() :
+ mnCol( -1 ),
+ mnRow( -1 ),
+ mnColOffset( 0 ),
+ mnRowOffset( 0 )
+{
+}
+
+// ----------------------------------------------------------------------------
+
+OoxAnchorClientData::OoxAnchorClientData() :
+ mbLocksWithSheet( true ),
+ mbPrintsWithSheet( true )
+{
+}
+
+// ============================================================================
+
+ShapeAnchor::ShapeAnchor( const WorksheetHelper& rHelper ) :
+ WorksheetHelper( rHelper ),
+ meType( ANCHOR_INVALID ),
+ mnEditAs( XML_twoCell )
+{
+}
+
+void ShapeAnchor::importAbsoluteAnchor( const AttributeList& )
+{
+ meType = ANCHOR_ABSOLUTE;
+}
+
+void ShapeAnchor::importOneCellAnchor( const AttributeList& )
+{
+ meType = ANCHOR_ONECELL;
+}
+
+void ShapeAnchor::importTwoCellAnchor( const AttributeList& rAttribs )
+{
+ meType = ANCHOR_TWOCELL;
+ mnEditAs = rAttribs.getToken( XML_editAs, XML_twoCell );
+}
+
+void ShapeAnchor::importPos( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( meType == ANCHOR_ABSOLUTE, "ShapeAnchor::importPos - unexpected 'xdr:pos' element" );
+ maPos.mnX = rAttribs.getInteger64( XML_x, 0 );
+ maPos.mnY = rAttribs.getInteger64( XML_y, 0 );
+}
+
+void ShapeAnchor::importExt( const AttributeList& rAttribs )
+{
+ OSL_ENSURE( (meType == ANCHOR_ABSOLUTE) || (meType == ANCHOR_ONECELL), "ShapeAnchor::importExt - unexpected 'xdr:ext' element" );
+ maSize.mnWidth = rAttribs.getInteger64( XML_cx, 0 );
+ maSize.mnHeight = rAttribs.getInteger64( XML_cy, 0 );
+}
+
+void ShapeAnchor::importClientData( const AttributeList& rAttribs )
+{
+ maClientData.mbLocksWithSheet = rAttribs.getBool( XML_fLocksWithSheet, true );
+ maClientData.mbPrintsWithSheet = rAttribs.getBool( XML_fPrintsWithSheet, true );
+}
+
+void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const OUString& rValue )
+{
+ OoxAnchorCell* pAnchorCell = 0;
+ switch( nParentContext )
+ {
+ case XDR_TOKEN( from ):
+ OSL_ENSURE( (meType == ANCHOR_ONECELL) || (meType == ANCHOR_TWOCELL), "ShapeAnchor::setCellPos - unexpected 'xdr:from' element" );
+ pAnchorCell = &maFrom;
+ break;
+ case XDR_TOKEN( to ):
+ OSL_ENSURE( meType == ANCHOR_TWOCELL, "ShapeAnchor::setCellPos - unexpected 'xdr:to' element" );
+ pAnchorCell = &maTo;
+ break;
+ default:
+ OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected parent element" );
+ }
+ if( pAnchorCell ) switch( nElement )
+ {
+ case XDR_TOKEN( col ): pAnchorCell->mnCol = rValue.toInt32(); break;
+ case XDR_TOKEN( row ): pAnchorCell->mnRow = rValue.toInt32(); break;
+ case XDR_TOKEN( colOff ): pAnchorCell->mnColOffset = rValue.toInt64(); break;
+ case XDR_TOKEN( rowOff ): pAnchorCell->mnRowOffset = rValue.toInt64(); break;
+ default: OSL_ENSURE( false, "ShapeAnchor::setCellPos - unexpected element" );
+ }
+}
+
+Rectangle ShapeAnchor::calcApiLocation( const Size& rApiSheetSize, const OoxAnchorSize& rEmuSheetSize ) const
+{
+ AddressConverter& rAddrConv = getAddressConverter();
+ UnitConverter& rUnitConv = getUnitConverter();
+ Rectangle aApiLoc( -1, -1, -1, -1 );
+
+ // calculate shape position
+ switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcApiLocation - invalid position" );
+ if( maPos.isValid() && (maPos.mnX < rEmuSheetSize.mnWidth) && (maPos.mnY < rEmuSheetSize.mnHeight) )
+ {
+ aApiLoc.X = rUnitConv.scaleToMm100( static_cast< double >( maPos.mnX ), UNIT_EMU );
+ aApiLoc.Y = rUnitConv.scaleToMm100( static_cast< double >( maPos.mnY ), UNIT_EMU );
+ }
+ break;
+ case ANCHOR_ONECELL:
+ case ANCHOR_TWOCELL:
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcApiLocation - invalid position" );
+ if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) )
+ {
+ Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow );
+ aApiLoc.X = aPoint.X + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnColOffset ), UNIT_EMU );
+ aApiLoc.Y = aPoint.Y + rUnitConv.scaleToMm100( static_cast< double >( maFrom.mnRowOffset ), UNIT_EMU );
+ }
+ break;
+ case ANCHOR_INVALID:
+ OSL_ENSURE( false, "ShapeAnchor::calcApiLocation - invalid anchor" );
+ break;
+ }
+
+ // calculate shape size
+ if( (aApiLoc.X >= 0) && (aApiLoc.Y >= 0) ) switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ case ANCHOR_ONECELL:
+ OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcApiLocation - invalid size" );
+ if( maSize.isValid() )
+ {
+ aApiLoc.Width = ::std::min< sal_Int32 >(
+ rUnitConv.scaleToMm100( static_cast< double >( maSize.mnWidth ), UNIT_EMU ),
+ rApiSheetSize.Width - aApiLoc.X );
+ aApiLoc.Height = ::std::min< sal_Int32 >(
+ rUnitConv.scaleToMm100( static_cast< double >( maSize.mnHeight ), UNIT_EMU ),
+ rApiSheetSize.Height - aApiLoc.Y );
+ }
+ break;
+ case ANCHOR_TWOCELL:
+ OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcApiLocation - invalid position" );
+ if( maTo.isValid() )
+ {
+ /* Pass a valid cell address to getCellPosition(), otherwise
+ nothing is returned, even if either row or column is valid. */
+ CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true );
+ Point aPoint = getCellPosition( aToCell.Column, aToCell.Row );
+ // width
+ aApiLoc.Width = rApiSheetSize.Width - aApiLoc.X;
+ if( aToCell.Column == maTo.mnCol )
+ {
+ aPoint.X += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnColOffset ), UNIT_EMU );
+ aApiLoc.Width = ::std::min< sal_Int32 >( aPoint.X - aApiLoc.X + 1, aApiLoc.Width );
+ }
+ // height
+ aApiLoc.Height = rApiSheetSize.Height - aApiLoc.Y;
+ if( aToCell.Row == maTo.mnRow )
+ {
+ aPoint.Y += rUnitConv.scaleToMm100( static_cast< double >( maTo.mnRowOffset ), UNIT_EMU );
+ aApiLoc.Height = ::std::min< sal_Int32 >( aPoint.Y - aApiLoc.Y + 1, aApiLoc.Height );
+ }
+ }
+ break;
+ case ANCHOR_INVALID:
+ break;
+ }
+
+ return aApiLoc;
+}
+
+Rectangle ShapeAnchor::calcEmuLocation( const OoxAnchorSize& rEmuSheetSize ) const
+{
+ AddressConverter& rAddrConv = getAddressConverter();
+ UnitConverter& rUnitConv = getUnitConverter();
+
+ Size aSheetSize(
+ getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.mnWidth, 0, SAL_MAX_INT32 ),
+ getLimitedValue< sal_Int32, sal_Int64 >( rEmuSheetSize.mnHeight, 0, SAL_MAX_INT32 ) );
+ Rectangle aLoc( -1, -1, -1, -1 );
+
+ // calculate shape position
+ switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ OSL_ENSURE( maPos.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" );
+ if( maPos.isValid() && (maPos.mnX < aSheetSize.Width) && (maPos.mnY < aSheetSize.Height) )
+ {
+ aLoc.X = static_cast< sal_Int32 >( maPos.mnX );
+ aLoc.Y = static_cast< sal_Int32 >( maPos.mnY );
+ }
+ break;
+ case ANCHOR_ONECELL:
+ case ANCHOR_TWOCELL:
+ OSL_ENSURE( maFrom.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" );
+ if( maFrom.isValid() && rAddrConv.checkCol( maFrom.mnCol, true ) && rAddrConv.checkRow( maFrom.mnRow, true ) )
+ {
+ Point aPoint = getCellPosition( maFrom.mnCol, maFrom.mnRow );
+ sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) ) + maFrom.mnColOffset;
+ sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) ) + maFrom.mnRowOffset;
+ if( (nX < aSheetSize.Width) && (nY < aSheetSize.Height) )
+ {
+ aLoc.X = static_cast< sal_Int32 >( nX );
+ aLoc.Y = static_cast< sal_Int32 >( nY );
+ }
+ }
+ break;
+ case ANCHOR_INVALID:
+ OSL_ENSURE( false, "ShapeAnchor::calcEmuLocation - invalid anchor" );
+ break;
+ }
+
+ // calculate shape size
+ if( (aLoc.X >= 0) && (aLoc.Y >= 0) ) switch( meType )
+ {
+ case ANCHOR_ABSOLUTE:
+ case ANCHOR_ONECELL:
+ OSL_ENSURE( maSize.isValid(), "ShapeAnchor::calcEmuLocation - invalid size" );
+ if( maSize.isValid() )
+ {
+ aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.mnWidth, aSheetSize.Width - aLoc.X ) );
+ aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( maSize.mnHeight, aSheetSize.Height - aLoc.Y ) );
+ }
+ break;
+ case ANCHOR_TWOCELL:
+ OSL_ENSURE( maTo.isValid(), "ShapeAnchor::calcEmuLocation - invalid position" );
+ if( maTo.isValid() )
+ {
+ /* Pass a valid cell address to getCellPosition(), otherwise
+ nothing is returned, even if either row or column is valid. */
+ CellAddress aToCell = rAddrConv.createValidCellAddress( BinAddress( maTo.mnCol, maTo.mnRow ), getSheetIndex(), true );
+ Point aPoint = getCellPosition( aToCell.Column, aToCell.Row );
+ sal_Int64 nX = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.X, UNIT_EMU ) );
+ sal_Int64 nY = static_cast< sal_Int64 >( rUnitConv.scaleFromMm100( aPoint.Y, UNIT_EMU ) );
+ // width
+ aLoc.Width = aSheetSize.Width - aLoc.X;
+ if( aToCell.Column == maTo.mnCol )
+ {
+ nX += maTo.mnColOffset;
+ aLoc.Width = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nX - aLoc.X + 1, aLoc.Width ) );
+ }
+ // height
+ aLoc.Height = aSheetSize.Height - aLoc.Y;
+ if( aToCell.Row == maTo.mnRow )
+ {
+ nY += maTo.mnRowOffset;
+ aLoc.Height = static_cast< sal_Int32 >( ::std::min< sal_Int64 >( nY - aLoc.Y + 1, aLoc.Height ) );
+ }
+ }
+ break;
+ case ANCHOR_INVALID:
+ break;
+ }
+
+ // add 1 mm (36K EMUs) in X direction to correct display error
+ if( aLoc.X >= 0 )
+ aLoc.X += 36000;
+
+ return aLoc;
+}
+
+// ============================================================================
+
+OoxDrawingFragment::OoxDrawingFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) :
+ OoxWorksheetFragmentBase( rHelper, rFragmentPath )
+{
+ Reference< XDrawPageSupplier > xDrawPageSupp( getXSpreadsheet(), UNO_QUERY );
+ if( xDrawPageSupp.is() )
+ mxDrawPage.set( xDrawPageSupp->getDrawPage(), UNO_QUERY );
+ OSL_ENSURE( mxDrawPage.is(), "OoxDrawingFragment::OoxDrawingFragment - missing drawing page" );
+
+ maApiSheetSize = getDrawPageSize();
+ maEmuSheetSize.mnWidth = static_cast< sal_Int64 >( getUnitConverter().scaleFromMm100( maApiSheetSize.Width, UNIT_EMU ) );
+ maEmuSheetSize.mnHeight = static_cast< sal_Int64 >( getUnitConverter().scaleFromMm100( maApiSheetSize.Height, UNIT_EMU ) );
+}
+
+// oox.core.ContextHandler2Helper interface -----------------------------------
+
+ContextWrapper OoxDrawingFragment::onCreateContext( sal_Int32 nElement, const AttributeList& )
+{
+ switch( getCurrentElement() )
+ {
+ case XML_ROOT_CONTEXT:
+ return (nElement == XDR_TOKEN( wsDr ));
+ case XDR_TOKEN( wsDr ):
+ return (nElement == XDR_TOKEN( absoluteAnchor )) ||
+ (nElement == XDR_TOKEN( oneCellAnchor )) ||
+ (nElement == XDR_TOKEN( twoCellAnchor ));
+ case XDR_TOKEN( absoluteAnchor ):
+ case XDR_TOKEN( oneCellAnchor ):
+ case XDR_TOKEN( twoCellAnchor ):
+ switch( nElement )
+ {
+ case XDR_TOKEN( sp ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.CustomShape" ) );
+ return new ShapeContext( *this, ShapePtr(), mxShape );
+ case XDR_TOKEN( cxnSp ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.ConnectorShape" ) );
+ return new ConnectorShapeContext( *this, ShapePtr(), mxShape );
+ case XDR_TOKEN( pic ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) );
+ return new GraphicShapeContext( *this, ShapePtr(), mxShape );
+ case XDR_TOKEN( graphicFrame ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.OLE2Shape" ) );
+ return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape );
+ case XDR_TOKEN( grpSp ):
+ mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) );
+ return new ShapeGroupContext( *this, ShapePtr(), mxShape );
+ }
+ return (nElement == XDR_TOKEN( pos )) ||
+ (nElement == XDR_TOKEN( ext )) ||
+ (nElement == XDR_TOKEN( from )) ||
+ (nElement == XDR_TOKEN( to )) ||
+ (nElement == XDR_TOKEN( clientData ));
+ case XDR_TOKEN( from ):
+ case XDR_TOKEN( to ):
+ return (nElement == XDR_TOKEN( col )) ||
+ (nElement == XDR_TOKEN( row )) ||
+ (nElement == XDR_TOKEN( colOff )) ||
+ (nElement == XDR_TOKEN( rowOff ));
+ }
+ return false;
+}
+
+void OoxDrawingFragment::onStartElement( const AttributeList& rAttribs )
+{
+ switch( getCurrentElement() )
+ {
+ case XDR_TOKEN( absoluteAnchor ):
+ mxAnchor.reset( new ShapeAnchor( *this ) );
+ mxAnchor->importAbsoluteAnchor( rAttribs );
+ break;
+ case XDR_TOKEN( oneCellAnchor ):
+ mxAnchor.reset( new ShapeAnchor( *this ) );
+ mxAnchor->importOneCellAnchor( rAttribs );
+ break;
+ case XDR_TOKEN( twoCellAnchor ):
+ mxAnchor.reset( new ShapeAnchor( *this ) );
+ mxAnchor->importTwoCellAnchor( rAttribs );
+ break;
+ case XDR_TOKEN( pos ):
+ if( mxAnchor.get() ) mxAnchor->importPos( rAttribs );
+ break;
+ case XDR_TOKEN( ext ):
+ if( mxAnchor.get() ) mxAnchor->importExt( rAttribs );
+ break;
+ case XDR_TOKEN( clientData ):
+ if( mxAnchor.get() ) mxAnchor->importClientData( rAttribs );
+ break;
+ }
+}
+
+void OoxDrawingFragment::onEndElement( const OUString& rChars )
+{
+ switch( getCurrentElement() )
+ {
+ case XDR_TOKEN( col ):
+ case XDR_TOKEN( row ):
+ case XDR_TOKEN( colOff ):
+ case XDR_TOKEN( rowOff ):
+ if( mxAnchor.get() ) mxAnchor->setCellPos( getCurrentElement(), getPreviousElement(), rChars );
+ break;
+ case XDR_TOKEN( absoluteAnchor ):
+ case XDR_TOKEN( oneCellAnchor ):
+ case XDR_TOKEN( twoCellAnchor ):
+ if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() )
+ {
+ Rectangle aLoc = mxAnchor->calcEmuLocation( maEmuSheetSize );
+ if( (aLoc.X >= 0) && (aLoc.Y >= 0) && (aLoc.Width >= 0) && (aLoc.Height >= 0) )
+ mxShape->addShape( getOoxFilter(), getTheme().getCoreThemePtr(), mxDrawPage, &aLoc );
+ }
+ mxShape.reset();
+ mxAnchor.reset();
+ break;
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+