diff options
Diffstat (limited to 'oox/source')
40 files changed, 1044 insertions, 387 deletions
diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index 902784cafe80..fb9e43c732de 100755..100644 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -130,10 +130,9 @@ enum FilterDirection struct FilterBaseImpl { - typedef ::boost::shared_ptr< GraphicHelper > GraphicHelperRef; - typedef ::boost::shared_ptr< ModelObjectHelper > ModelObjHelperRef; - typedef ::boost::shared_ptr< OleObjectHelper > OleObjHelperRef; - typedef ::std::map< OUString, Reference< XGraphic > > EmbeddedGraphicMap; + typedef ::boost::shared_ptr< GraphicHelper > GraphicHelperRef; + typedef ::boost::shared_ptr< ModelObjectHelper > ModelObjHelperRef; + typedef ::boost::shared_ptr< OleObjectHelper > OleObjHelperRef; FilterDirection meDirection; SequenceAsHashMap maArguments; @@ -144,7 +143,6 @@ struct FilterBaseImpl GraphicHelperRef mxGraphicHelper; /// Graphic and graphic object handling. ModelObjHelperRef mxModelObjHelper; /// Tables to create new named drawing objects. OleObjHelperRef mxOleObjHelper; /// OLE object handling. - EmbeddedGraphicMap maEmbeddedGraphics; /// Maps all imported embedded graphics by their path. Reference< XMultiServiceFactory > mxGlobalFactory; Reference< XModel > mxModel; @@ -200,11 +198,7 @@ void FilterBaseImpl::finalizeFilter() { try { - // clear the 'ComponentData' property in the descriptor - MediaDescriptor::iterator aIt = maMediaDesc.find( MediaDescriptor::PROP_COMPONENTDATA() ); - if( aIt != maMediaDesc.end() ) - aIt->second.clear(); - // write the descriptor back to the document model (adds the password) + // write the descriptor back to the document model (adds the passwords) mxModel->attachResource( maFileUrl, maMediaDesc.getAsConstPropertyValueList() ); // unlock the model controllers mxModel->unlockControllers(); @@ -248,11 +242,6 @@ const Reference< XMultiServiceFactory >& FilterBase::getGlobalFactory() const return mxImpl->mxGlobalFactory; } -MediaDescriptor& FilterBase::getMediaDescriptor() const -{ - return mxImpl->maMediaDesc; -} - const Reference< XModel >& FilterBase::getModel() const { return mxImpl->mxModel; @@ -278,6 +267,11 @@ const Reference< XInteractionHandler >& FilterBase::getInteractionHandler() cons return mxImpl->mxInteractionHandler; } +MediaDescriptor& FilterBase::getMediaDescriptor() const +{ + return mxImpl->maMediaDesc; +} + const OUString& FilterBase::getFileUrl() const { return mxImpl->maFileUrl; @@ -423,31 +417,6 @@ bool FilterBase::importBinaryData( StreamDataSequence& orDataSeq, const OUString return true; } -Reference< XGraphic > FilterBase::importEmbeddedGraphic( const OUString& rStreamName ) const -{ - Reference< XGraphic > xGraphic; - OSL_ENSURE( rStreamName.getLength() > 0, "FilterBase::importEmbeddedGraphic - empty stream name" ); - if( rStreamName.getLength() > 0 ) - { - FilterBaseImpl::EmbeddedGraphicMap::const_iterator aIt = mxImpl->maEmbeddedGraphics.find( rStreamName ); - if( aIt == mxImpl->maEmbeddedGraphics.end() ) - { - xGraphic = getGraphicHelper().importGraphic( openInputStream( rStreamName ) ); - if( xGraphic.is() ) - mxImpl->maEmbeddedGraphics[ rStreamName ] = xGraphic; - } - else - xGraphic = aIt->second; - } - return xGraphic; -} - -OUString FilterBase::importEmbeddedGraphicObject( const OUString& rStreamName ) const -{ - Reference< XGraphic > xGraphic = importEmbeddedGraphic( rStreamName ); - return xGraphic.is() ? getGraphicHelper().createGraphicObject( xGraphic ) : OUString(); -} - // com.sun.star.lang.XServiceInfo interface ----------------------------------- OUString SAL_CALL FilterBase::getImplementationName() throw( RuntimeException ) @@ -560,7 +529,7 @@ Reference< XStream > FilterBase::implGetOutputStream( MediaDescriptor& rMediaDes void FilterBase::setMediaDescriptor( const Sequence< PropertyValue >& rMediaDescSeq ) { - mxImpl->maMediaDesc = rMediaDescSeq; + mxImpl->maMediaDesc << rMediaDescSeq; switch( mxImpl->meDirection ) { @@ -587,7 +556,7 @@ void FilterBase::setMediaDescriptor( const Sequence< PropertyValue >& rMediaDesc GraphicHelper* FilterBase::implCreateGraphicHelper() const { // default: return base implementation without any special behaviour - return new GraphicHelper( mxImpl->mxGlobalFactory, mxImpl->mxTargetFrame ); + return new GraphicHelper( mxImpl->mxGlobalFactory, mxImpl->mxTargetFrame, mxImpl->mxStorage ); } // ============================================================================ diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index 12cafc48305a..00244c224778 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -41,6 +41,7 @@ #include "oox/ole/olestorage.hxx" using ::rtl::OUString; +using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::RuntimeException; @@ -474,9 +475,7 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript return xInStrm; // check if a temporary file is passed in the 'ComponentData' property - Sequence< NamedValue > aCompData = rMediaDesc.getUnpackedValueOrDefault( MediaDescriptor::PROP_COMPONENTDATA(), Sequence< NamedValue >() ); - SequenceAsHashMap aCompDataMap( aCompData ); - Reference< XStream > xDecrypted = aCompDataMap.getUnpackedValueOrDefault( CREATE_OUSTRING( "DecryptedPackage" ), Reference< XStream >() ); + Reference< XStream > xDecrypted( rMediaDesc.getComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ) ), UNO_QUERY ); if( xDecrypted.is() ) { Reference< XInputStream > xDecrInStrm = xDecrypted->getInputStream(); @@ -559,10 +558,7 @@ Reference< XInputStream > FilterDetect::extractUnencryptedPackage( MediaDescript aDecryptedPackage.seekToStart(); // store temp file in media descriptor to keep it alive - Sequence< NamedValue > aPropSeq( 1 ); - aPropSeq[ 0 ].Name = CREATE_OUSTRING( "DecryptedPackage" ); - aPropSeq[ 0 ].Value <<= xTempFile; - rMediaDesc[ MediaDescriptor::PROP_COMPONENTDATA() ] <<= aPropSeq; + rMediaDesc.setComponentDataEntry( CREATE_OUSTRING( "DecryptedPackage" ), Any( xTempFile ) ); Reference< XInputStream > xDecrInStrm = xTempFile->getInputStream(); if( lclIsZipPackage( mxFactory, xDecrInStrm ) ) diff --git a/oox/source/docprop/docprophandler.cxx b/oox/source/docprop/docprophandler.cxx index 97453d5bddb0..1830a8c5d5f9 100644 --- a/oox/source/docprop/docprophandler.cxx +++ b/oox/source/docprop/docprophandler.cxx @@ -618,7 +618,7 @@ void SAL_CALL OOXMLDocPropHandler::characters( const ::rtl::OUString& aChars ) case XML_bstr|NMSP_VT: case XML_lpstr|NMSP_VT: case XML_lpwstr|NMSP_VT: - AddCustomProperty( uno::makeAny( AttributeList::decodeXString( aChars ) ) ); // the property has string type + AddCustomProperty( uno::makeAny( AttributeConversion::decodeXString( aChars ) ) ); // the property has string type break; case XML_date|NMSP_VT: diff --git a/oox/source/drawingml/fillpropertiesgroupcontext.cxx b/oox/source/drawingml/fillpropertiesgroupcontext.cxx index 8adffb265240..b9d7fa7e1142 100644 --- a/oox/source/drawingml/fillpropertiesgroupcontext.cxx +++ b/oox/source/drawingml/fillpropertiesgroupcontext.cxx @@ -27,6 +27,7 @@ #include "oox/drawingml/fillpropertiesgroupcontext.hxx" #include "oox/helper/attributelist.hxx" +#include "oox/helper/graphichelper.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/xmlfilterbase.hxx" #include "oox/drawingml/drawingmltypes.hxx" @@ -170,7 +171,7 @@ BlipContext::BlipContext( ContextHandler& rParent, // internal picture URL OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( embed ), OUString() ) ); if( aFragmentPath.getLength() > 0 ) - mrBlipProps.mxGraphic = getFilter().importEmbeddedGraphic( aFragmentPath ); + mrBlipProps.mxGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic( aFragmentPath ); } else if( aAttribs.hasAttribute( R_TOKEN( link ) ) ) { diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx index 8537017c2118..48461bb2858e 100644 --- a/oox/source/drawingml/graphicshapecontext.cxx +++ b/oox/source/drawingml/graphicshapecontext.cxx @@ -36,6 +36,7 @@ #include "oox/core/namespaces.hxx" #include "oox/core/xmlfilterbase.hxx" #include "oox/helper/attributelist.hxx" +#include "oox/helper/graphichelper.hxx" #include "oox/helper/propertyset.hxx" #include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmlshape.hxx" @@ -190,7 +191,7 @@ OUString CreateOleObjectCallback::onCreateXShape( const OUString&, const awt::Re // import and store the graphic if( aGraphicPath.getLength() > 0 ) { - Reference< graphic::XGraphic > xGraphic = mrFilter.importEmbeddedGraphic( aGraphicPath ); + Reference< graphic::XGraphic > xGraphic = mrFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath ); if( xGraphic.is() ) maShapeProps[ PROP_Graphic ] <<= xGraphic; } diff --git a/oox/source/drawingml/textbodyproperties.cxx b/oox/source/drawingml/textbodyproperties.cxx index afd4766b0106..6cec7643e58e 100644 --- a/oox/source/drawingml/textbodyproperties.cxx +++ b/oox/source/drawingml/textbodyproperties.cxx @@ -2,13 +2,10 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2008 by Sun Microsystems, Inc. + * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * - * $RCSfile: textbodyproperties.cxx,v $ - * $Revision: 1.1 $ - * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify diff --git a/oox/source/dump/biffdumper.cxx b/oox/source/dump/biffdumper.cxx index aa32cbe53d1b..30938f9ebbe6 100644 --- a/oox/source/dump/biffdumper.cxx +++ b/oox/source/dump/biffdumper.cxx @@ -2532,6 +2532,11 @@ void WorkbookStreamObject::implDumpRecordBody() dumpObjRec(); break; + case BIFF_ID_OLESIZE: + dumpUnused( 2 ); + dumpRange( "visible-range", false ); + break; + case BIFF_ID_PAGELAYOUTVIEW: dumpFrHeader( true, true ); dumpDec< sal_uInt16 >( "scaling", "CONV-PERCENT" ); diff --git a/oox/source/dump/biffdumper.ini b/oox/source/dump/biffdumper.ini index 2d1f4bdf7897..d4b862825b3c 100644 --- a/oox/source/dump/biffdumper.ini +++ b/oox/source/dump/biffdumper.ini @@ -2075,6 +2075,7 @@ flagslist=XF-PROTECTION-FLAGS 0x01=locked 0x02=formula-hidden 0x04=style-xf + 0x08=apostroph-quote end flagslist=XF-USEDATTRIBS-FLAGS diff --git a/oox/source/dump/dumperbase.ini b/oox/source/dump/dumperbase.ini index 84d742c2b35f..34ef302c784c 100644 --- a/oox/source/dump/dumperbase.ini +++ b/oox/source/dump/dumperbase.ini @@ -254,7 +254,7 @@ end combilist=RK-FLAGS 0x00000001=div-100 0x00000002=integer - 0xFFFFFFFC=int32,dec,value,,filter=0x2~0x2 + 0xFFFFFFFC=int32,hex,value end constlist=CHARSET diff --git a/oox/source/dump/oledumper.ini b/oox/source/dump/oledumper.ini index 7efe424b0ddc..13478464e6b3 100644 --- a/oox/source/dump/oledumper.ini +++ b/oox/source/dump/oledumper.ini @@ -206,7 +206,7 @@ shortlist=COMCTL-SCROLLBAR-ARROWS,0,both,left-up,right-down constlist=COMCTL-SLIDER-SELECTRANGE 0x00000000=off 0x0000FFFF=on - end +end shortlist=COMCTL-SLIDER-TICKSTYLE,0,bottom-right,top-left,both,no-ticks @@ -218,13 +218,13 @@ shortlist=COMCTL-SLIDER-TICKSTYLE,0,bottom-right,top-left,both,no-ticks flagslist=COMCTL-UPDOWN-FLAGS1 0x00000001=!align-left!align-right 0x00000004=!vertical!horizontal - end +end flagslist=COMCTL-UPDOWN-FLAGS2 0x00000004=wrap 0x00000020=ole-drop-manual 0x00000080=enabled - end +end # image list ----------------------------------------------------------------- @@ -725,11 +725,6 @@ combilist=VBA-FORMSITE-CLASSIDCACHE 0x8000=!predefined-class-id!class-table-index end -constlist=VBA-FORMSITE-CLASSIDCACHEINDEX - include=VBA-FORMSITE-CLASSNAMES - 0x7FFF=invalid -end - constlist=VBA-FORMSITE-CLASSNAMES 7=Forms.Form.1 12=Forms.Image.1 @@ -749,6 +744,11 @@ constlist=VBA-FORMSITE-CLASSNAMES 57=Forms.MultiPage.1 end +constlist=VBA-FORMSITE-CLASSIDCACHEINDEX + include=VBA-FORMSITE-CLASSNAMES + 0x7FFF=invalid +end + # form design extender ------------------------------------------------------ flagslist=VBA-FORMDESIGNEXT-PROPERTIES diff --git a/oox/source/dump/xlsbdumper.cxx b/oox/source/dump/xlsbdumper.cxx index 80fccddff2ea..dd78ac3c4e2e 100644 --- a/oox/source/dump/xlsbdumper.cxx +++ b/oox/source/dump/xlsbdumper.cxx @@ -1626,6 +1626,10 @@ void RecordStreamObject::implDumpRecordBody() } break; + case OOBIN_ID_OLESIZE: + dumpRange( "visible-range" ); + break; + case OOBIN_ID_PAGEMARGINS: dumpDec< double >( "left-margin" ); dumpDec< double >( "right-margin" ); diff --git a/oox/source/dump/xlsbdumper.ini b/oox/source/dump/xlsbdumper.ini index d8bc97ddb6bc..f2ac3b49b4d6 100644 --- a/oox/source/dump/xlsbdumper.ini +++ b/oox/source/dump/xlsbdumper.ini @@ -216,7 +216,7 @@ multilist=RECORD-NAMES 0x0208=VOLTYPETP,VOLTYPETP_END,VOLTYPESTP,VOLTYPETR,,VOLTYPE_ERROR,, 0x0210=CALCCHAIN,CALCCHAIN_END,,,,,,SHEETPROTECTION 0x0218=,PHONETICPR,,,,,, - 0x0220=,,,,,,DRAWING,LEGACYDRAWING + 0x0220=,,,,,OLESIZE,DRAWING,LEGACYDRAWING 0x0230=,,PICTURE,,CFCOLOR,INDEXEDCOLORS,INDEXEDCOLORS_END, 0x0238=,MRUCOLORS,MRUCOLORS_END,,COLOR,DATAVALIDATIONS,DATAVALIDATIONS_END, diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx index 4e121497c452..5479fae46f82 100644 --- a/oox/source/helper/attributelist.cxx +++ b/oox/source/helper/attributelist.cxx @@ -72,22 +72,9 @@ sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd ) } // namespace -// ============================================================================ - -AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) : - mxAttribs( rxAttribs ) -{ - OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" ); -} - -bool AttributeList::hasAttribute( sal_Int32 nElement ) const -{ - return mxAttribs->hasAttribute( nElement ); -} - -// static string conversion ----------------------------------------------- +// ---------------------------------------------------------------------------- -OUString AttributeList::decodeXString( const OUString& rValue ) +OUString AttributeConversion::decodeXString( const OUString& rValue ) { // string shorter than one encoded character - no need to decode if( rValue.getLength() < XSTRING_ENCCHAR_LEN ) @@ -100,127 +87,146 @@ OUString AttributeList::decodeXString( const OUString& rValue ) return aBuffer.makeStringAndClear(); } -double AttributeList::decodeDouble( const OUString& rValue ) +double AttributeConversion::decodeDouble( const OUString& rValue ) { return rValue.toDouble(); } -sal_Int32 AttributeList::decodeInteger( const OUString& rValue ) +sal_Int32 AttributeConversion::decodeInteger( const OUString& rValue ) { return rValue.toInt32(); } -sal_uInt32 AttributeList::decodeUnsigned( const OUString& rValue ) +sal_uInt32 AttributeConversion::decodeUnsigned( const OUString& rValue ) { return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64(), 0, SAL_MAX_UINT32 ); } -sal_Int64 AttributeList::decodeHyper( const OUString& rValue ) +sal_Int64 AttributeConversion::decodeHyper( const OUString& rValue ) { return rValue.toInt64(); } -sal_Int32 AttributeList::decodeIntegerHex( const OUString& rValue ) +sal_Int32 AttributeConversion::decodeIntegerHex( const OUString& rValue ) { return rValue.toInt32( 16 ); } -sal_uInt32 AttributeList::decodeUnsignedHex( const OUString& rValue ) +sal_uInt32 AttributeConversion::decodeUnsignedHex( const OUString& rValue ) { return getLimitedValue< sal_uInt32, sal_Int64 >( rValue.toInt64( 16 ), 0, SAL_MAX_UINT32 ); } -sal_Int64 AttributeList::decodeHyperHex( const OUString& rValue ) +sal_Int64 AttributeConversion::decodeHyperHex( const OUString& rValue ) { return rValue.toInt64( 16 ); } +// ============================================================================ + +AttributeList::AttributeList( const Reference< XFastAttributeList >& rxAttribs ) : + mxAttribs( rxAttribs ) +{ + OSL_ENSURE( mxAttribs.is(), "AttributeList::AttributeList - missing attribute list interface" ); +} + +bool AttributeList::hasAttribute( sal_Int32 nAttrToken ) const +{ + return mxAttribs->hasAttribute( nAttrToken ); +} + // optional return values ----------------------------------------------------- -OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nElement ) const +OptValue< sal_Int32 > AttributeList::getToken( sal_Int32 nAttrToken ) const { - sal_Int32 nToken = mxAttribs->getOptionalValueToken( nElement, XML_TOKEN_INVALID ); + sal_Int32 nToken = mxAttribs->getOptionalValueToken( nAttrToken, XML_TOKEN_INVALID ); return OptValue< sal_Int32 >( nToken != XML_TOKEN_INVALID, nToken ); } -OptValue< OUString > AttributeList::getString( sal_Int32 nElement ) const +OptValue< OUString > AttributeList::getString( sal_Int32 nAttrToken ) const { - return OptValue< OUString >( mxAttribs->hasAttribute( nElement ), mxAttribs->getOptionalValue( nElement ) ); + // check if the attribute exists (empty string may be different to missing attribute) + if( mxAttribs->hasAttribute( nAttrToken ) ) + return OptValue< OUString >( mxAttribs->getOptionalValue( nAttrToken ) ); + return OptValue< OUString >(); } -OptValue< OUString > AttributeList::getXString( sal_Int32 nElement ) const +OptValue< OUString > AttributeList::getXString( sal_Int32 nAttrToken ) const { - return OptValue< OUString >( mxAttribs->hasAttribute( nElement ), decodeXString( mxAttribs->getOptionalValue( nElement ) ) ); + // check if the attribute exists (empty string may be different to missing attribute) + if( mxAttribs->hasAttribute( nAttrToken ) ) + return OptValue< OUString >( AttributeConversion::decodeXString( mxAttribs->getOptionalValue( nAttrToken ) ) ); + return OptValue< OUString >(); } -OptValue< double > AttributeList::getDouble( sal_Int32 nElement ) const +OptValue< double > AttributeList::getDouble( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< double >( bValid, bValid ? decodeDouble( aValue ) : 0.0 ); + return OptValue< double >( bValid, bValid ? AttributeConversion::decodeDouble( aValue ) : 0.0 ); } -OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nElement ) const +OptValue< sal_Int32 > AttributeList::getInteger( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< sal_Int32 >( bValid, bValid ? decodeInteger( aValue ) : 0 ); + return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeInteger( aValue ) : 0 ); } -OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nElement ) const +OptValue< sal_uInt32 > AttributeList::getUnsigned( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< sal_uInt32 >( bValid, decodeUnsigned( aValue ) ); + return OptValue< sal_uInt32 >( bValid, AttributeConversion::decodeUnsigned( aValue ) ); } -OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nElement ) const +OptValue< sal_Int64 > AttributeList::getHyper( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< sal_Int64 >( bValid, bValid ? decodeHyper( aValue ) : 0 ); + return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyper( aValue ) : 0 ); } -OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nElement ) const +OptValue< sal_Int32 > AttributeList::getIntegerHex( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< sal_Int32 >( bValid, bValid ? decodeIntegerHex( aValue ) : 0 ); + return OptValue< sal_Int32 >( bValid, bValid ? AttributeConversion::decodeIntegerHex( aValue ) : 0 ); } -OptValue< sal_uInt32 > AttributeList::getUnsignedHex( sal_Int32 nElement ) const +OptValue< sal_uInt32 > AttributeList::getUnsignedHex( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< sal_uInt32 >( bValid, bValid ? decodeUnsignedHex( aValue ) : 0 ); + return OptValue< sal_uInt32 >( bValid, bValid ? AttributeConversion::decodeUnsignedHex( aValue ) : 0 ); } -OptValue< sal_Int64 > AttributeList::getHyperHex( sal_Int32 nElement ) const +OptValue< sal_Int64 > AttributeList::getHyperHex( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); bool bValid = aValue.getLength() > 0; - return OptValue< sal_Int64 >( bValid, bValid ? decodeHyperHex( aValue ) : 0 ); + return OptValue< sal_Int64 >( bValid, bValid ? AttributeConversion::decodeHyperHex( aValue ) : 0 ); } -OptValue< bool > AttributeList::getBool( sal_Int32 nElement ) const +OptValue< bool > AttributeList::getBool( sal_Int32 nAttrToken ) const { // boolean attributes may be "t", "f", "true", "false", "on", "off", "1", or "0" - switch( getToken( nElement, -1 ) ) + switch( getToken( nAttrToken, XML_TOKEN_INVALID ) ) { - case XML_t: return OptValue< bool >( true, true ); // used in VML - case XML_true: return OptValue< bool >( true, true ); - case XML_on: return OptValue< bool >( true, true ); - case XML_f: return OptValue< bool >( true, false ); // used in VML - case XML_false: return OptValue< bool >( true, false ); - case XML_off: return OptValue< bool >( true, false ); + case XML_t: return OptValue< bool >( true ); // used in VML + case XML_true: return OptValue< bool >( true ); + case XML_on: return OptValue< bool >( true ); + case XML_f: return OptValue< bool >( false ); // used in VML + case XML_false: return OptValue< bool >( false ); + case XML_off: return OptValue< bool >( false ); } - OptValue< sal_Int32 > onValue = getInteger( nElement ); + OptValue< sal_Int32 > onValue = getInteger( nAttrToken ); return OptValue< bool >( onValue.has(), onValue.get() != 0 ); } -OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nElement ) const +OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nAttrToken ) const { - OUString aValue = mxAttribs->getOptionalValue( nElement ); + OUString aValue = mxAttribs->getOptionalValue( nAttrToken ); DateTime aDateTime; bool bValid = (aValue.getLength() == 19) && (aValue[ 4 ] == '-') && (aValue[ 7 ] == '-') && (aValue[ 10 ] == 'T') && (aValue[ 13 ] == ':') && (aValue[ 16 ] == ':'); @@ -238,16 +244,16 @@ OptValue< DateTime > AttributeList::getDateTime( sal_Int32 nElement ) const // defaulted return values ---------------------------------------------------- -sal_Int32 AttributeList::getToken( sal_Int32 nElement, sal_Int32 nDefault ) const +sal_Int32 AttributeList::getToken( sal_Int32 nAttrToken, sal_Int32 nDefault ) const { - return mxAttribs->getOptionalValueToken( nElement, nDefault ); + return mxAttribs->getOptionalValueToken( nAttrToken, nDefault ); } -OUString AttributeList::getString( sal_Int32 nElement, const OUString& rDefault ) const +OUString AttributeList::getString( sal_Int32 nAttrToken, const OUString& rDefault ) const { try { - return mxAttribs->getValue( nElement ); + return mxAttribs->getValue( nAttrToken ); } catch( Exception& ) { @@ -255,54 +261,54 @@ OUString AttributeList::getString( sal_Int32 nElement, const OUString& rDefault return rDefault; } -OUString AttributeList::getXString( sal_Int32 nElement, const OUString& rDefault ) const +OUString AttributeList::getXString( sal_Int32 nAttrToken, const OUString& rDefault ) const { - return getXString( nElement ).get( rDefault ); + return getXString( nAttrToken ).get( rDefault ); } -double AttributeList::getDouble( sal_Int32 nElement, double fDefault ) const +double AttributeList::getDouble( sal_Int32 nAttrToken, double fDefault ) const { - return getDouble( nElement ).get( fDefault ); + return getDouble( nAttrToken ).get( fDefault ); } -sal_Int32 AttributeList::getInteger( sal_Int32 nElement, sal_Int32 nDefault ) const +sal_Int32 AttributeList::getInteger( sal_Int32 nAttrToken, sal_Int32 nDefault ) const { - return getInteger( nElement ).get( nDefault ); + return getInteger( nAttrToken ).get( nDefault ); } -sal_uInt32 AttributeList::getUnsigned( sal_Int32 nElement, sal_uInt32 nDefault ) const +sal_uInt32 AttributeList::getUnsigned( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const { - return getUnsigned( nElement ).get( nDefault ); + return getUnsigned( nAttrToken ).get( nDefault ); } -sal_Int64 AttributeList::getHyper( sal_Int32 nElement, sal_Int64 nDefault ) const +sal_Int64 AttributeList::getHyper( sal_Int32 nAttrToken, sal_Int64 nDefault ) const { - return getHyper( nElement ).get( nDefault ); + return getHyper( nAttrToken ).get( nDefault ); } -sal_Int32 AttributeList::getIntegerHex( sal_Int32 nElement, sal_Int32 nDefault ) const +sal_Int32 AttributeList::getIntegerHex( sal_Int32 nAttrToken, sal_Int32 nDefault ) const { - return getIntegerHex( nElement ).get( nDefault ); + return getIntegerHex( nAttrToken ).get( nDefault ); } -sal_uInt32 AttributeList::getUnsignedHex( sal_Int32 nElement, sal_uInt32 nDefault ) const +sal_uInt32 AttributeList::getUnsignedHex( sal_Int32 nAttrToken, sal_uInt32 nDefault ) const { - return getUnsignedHex( nElement ).get( nDefault ); + return getUnsignedHex( nAttrToken ).get( nDefault ); } -sal_Int64 AttributeList::getHyperHex( sal_Int32 nElement, sal_Int64 nDefault ) const +sal_Int64 AttributeList::getHyperHex( sal_Int32 nAttrToken, sal_Int64 nDefault ) const { - return getHyperHex( nElement ).get( nDefault ); + return getHyperHex( nAttrToken ).get( nDefault ); } -bool AttributeList::getBool( sal_Int32 nElement, bool bDefault ) const +bool AttributeList::getBool( sal_Int32 nAttrToken, bool bDefault ) const { - return getBool( nElement ).get( bDefault ); + return getBool( nAttrToken ).get( bDefault ); } -DateTime AttributeList::getDateTime( sal_Int32 nElement, const DateTime& rDefault ) const +DateTime AttributeList::getDateTime( sal_Int32 nAttrToken, const DateTime& rDefault ) const { - return getDateTime( nElement ).get( rDefault ); + return getDateTime( nAttrToken ).get( rDefault ); } // ============================================================================ diff --git a/oox/source/helper/graphichelper.cxx b/oox/source/helper/graphichelper.cxx index 6b294f61abef..455778f939f7 100644 --- a/oox/source/helper/graphichelper.cxx +++ b/oox/source/helper/graphichelper.cxx @@ -76,8 +76,9 @@ inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm // ============================================================================ -GraphicHelper::GraphicHelper( const Reference< XMultiServiceFactory >& rxGlobalFactory, const Reference< XFrame >& rxTargetFrame ) : +GraphicHelper::GraphicHelper( const Reference< XMultiServiceFactory >& rxGlobalFactory, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) : mxGraphicProvider( rxGlobalFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ), + mxStorage( rxStorage ), maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) ) { ::comphelper::ComponentContext aContext( rxGlobalFactory ); @@ -149,6 +150,8 @@ GraphicHelper::~GraphicHelper() { } +// System colors and predefined colors ---------------------------------------- + sal_Int32 GraphicHelper::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) const { return ContainerHelper::getMapElement( maSystemPalette, nToken, nDefaultRgb ); @@ -166,6 +169,8 @@ sal_Int32 GraphicHelper::getPaletteColor( sal_Int32 /*nPaletteIdx*/ ) const return API_RGB_TRANSPARENT; } +// Device info and device dependent unit conversion --------------------------- + const DeviceInfo& GraphicHelper::getDeviceInfo() const { return maDeviceInfo; @@ -267,6 +272,8 @@ Size GraphicHelper::convertHmmToAppFont( const Size& rHmm ) const return Size( 0, 0 ); } +// Graphics and graphic objects ---------------------------------------------- + Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm ) const { Reference< XGraphic > xGraphic; @@ -294,6 +301,25 @@ Reference< XGraphic > GraphicHelper::importGraphic( const StreamDataSequence& rG return xGraphic; } +Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName ) const +{ + Reference< XGraphic > xGraphic; + OSL_ENSURE( rStreamName.getLength() > 0, "GraphicHelper::importEmbeddedGraphic - empty stream name" ); + if( rStreamName.getLength() > 0 ) + { + EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find( rStreamName ); + if( aIt == maEmbeddedGraphics.end() ) + { + xGraphic = importGraphic( mxStorage->openInputStream( rStreamName ) ); + if( xGraphic.is() ) + maEmbeddedGraphics[ rStreamName ] = xGraphic; + } + else + xGraphic = aIt->second; + } + return xGraphic; +} + OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const { OUString aGraphicObjUrl; @@ -320,6 +346,12 @@ OUString GraphicHelper::importGraphicObject( const StreamDataSequence& rGraphicD return createGraphicObject( importGraphic( rGraphicData ) ); } +OUString GraphicHelper::importEmbeddedGraphicObject( const OUString& rStreamName ) const +{ + Reference< XGraphic > xGraphic = importEmbeddedGraphic( rStreamName ); + return xGraphic.is() ? createGraphicObject( xGraphic ) : OUString(); +} + // ============================================================================ } // namespace oox diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx index cb7e292b8cf4..68a18932bf42 100755 --- a/oox/source/ole/axbinaryreader.cxx +++ b/oox/source/ole/axbinaryreader.cxx @@ -156,6 +156,30 @@ bool AxFontData::importGuidAndFont( BinaryInputStream& rInStrm ) // ============================================================================ +namespace { + +bool lclReadString( AxAlignedInputStream& rInStrm, OUString& rValue, sal_uInt32 nSize, bool bArrayString ) +{ + bool bCompressed = getFlag( nSize, AX_STRING_COMPRESSED ); + sal_uInt32 nBufSize = nSize & AX_STRING_SIZEMASK; + // Unicode: simple strings store byte count, array strings store char count + sal_Int32 nChars = static_cast< sal_Int32 >( nBufSize / ((bCompressed || bArrayString) ? 1 : 2) ); + bool bValidChars = nChars <= 65536; + OSL_ENSURE( bValidChars, "lclReadString - string too long" ); + sal_Int64 nEndPos = rInStrm.tell() + nChars * (bCompressed ? 1 : 2); + nChars = ::std::min< sal_Int32 >( nChars, 65536 ); + rValue = bCompressed ? + // ISO-8859-1 maps all byte values xx to the same Unicode code point U+00xx + rInStrm.readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1 ) : + rInStrm.readUnicodeArray( nChars ); + rInStrm.seek( nEndPos ); + return bValidChars; +} + +} // namespace + +// ---------------------------------------------------------------------------- + AxBinaryPropertyReader::ComplexProperty::~ComplexProperty() { } @@ -168,19 +192,22 @@ bool AxBinaryPropertyReader::PairProperty::readProperty( AxAlignedInputStream& r bool AxBinaryPropertyReader::StringProperty::readProperty( AxAlignedInputStream& rInStrm ) { - bool bCompressed = getFlag( mnSize, AX_STRING_COMPRESSED ); - sal_uInt32 nBufSize = mnSize & AX_STRING_SIZEMASK; - sal_Int64 nEndPos = rInStrm.tell() + nBufSize; - sal_Int32 nChars = static_cast< sal_Int32 >( nBufSize / (bCompressed ? 1 : 2) ); - bool bValidChars = nChars <= 65536; - OSL_ENSURE( bValidChars, "StringProperty::readProperty - string too long" ); - nChars = ::std::min< sal_Int32 >( nChars, 65536 ); - mrValue = bCompressed ? - // ISO-8859-1 maps all byte values xx to the same Unicode code point U+00xx - rInStrm.readCharArrayUC( nChars, RTL_TEXTENCODING_ISO_8859_1 ) : - rInStrm.readUnicodeArray( nChars ); - rInStrm.seek( nEndPos ); - return bValidChars; + return lclReadString( rInStrm, mrValue, mnSize, false ); +} + +bool AxBinaryPropertyReader::StringArrayProperty::readProperty( AxAlignedInputStream& rInStrm ) +{ + sal_Int64 nEndPos = rInStrm.tell() + mnSize; + while( rInStrm.tell() < nEndPos ) + { + OUString aString; + if( !lclReadString( rInStrm, aString, rInStrm.readuInt32(), true ) ) + return false; + mrArray.push_back( aString ); + // every array string is aligned on 4 byte boundries + rInStrm.align( 4 ); + } + return true; } bool AxBinaryPropertyReader::GuidProperty::readProperty( AxAlignedInputStream& rInStrm ) @@ -238,6 +265,15 @@ void AxBinaryPropertyReader::readStringProperty( OUString& orValue ) } } +void AxBinaryPropertyReader::readStringArrayProperty( AxStringArray& orArray ) +{ + if( startNextProperty() ) + { + sal_uInt32 nSize = maInStrm.readAligned< sal_uInt32 >(); + maLargeProps.push_back( ComplexPropVector::value_type( new StringArrayProperty( orArray, nSize ) ) ); + } +} + void AxBinaryPropertyReader::readGuidProperty( ::rtl::OUString& orGuid ) { if( startNextProperty() ) diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx index 95d5c7dc67b7..82616026a505 100644 --- a/oox/source/ole/axcontrol.cxx +++ b/oox/source/ole/axcontrol.cxx @@ -128,6 +128,7 @@ const sal_uInt32 AX_IMAGE_DEFFLAGS = 0x0000001B; const sal_uInt32 AX_MORPHDATA_DEFFLAGS = 0x2C80081B; const sal_uInt32 AX_SPINBUTTON_DEFFLAGS = 0x0000001B; const sal_uInt32 AX_SCROLLBAR_DEFFLAGS = 0x0000001B; +const sal_uInt32 AX_TABSTRIP_DEFFLAGS = 0x0000001B; const sal_uInt16 AX_POS_TOPLEFT = 0; const sal_uInt16 AX_POS_TOP = 1; @@ -186,6 +187,10 @@ const sal_Int32 AX_ORIENTATION_HORIZONTAL = 1; const sal_Int32 AX_PROPTHUMB_ON = -1; const sal_Int32 AX_PROPTHUMB_OFF = 0; +const sal_uInt32 AX_TABSTRIP_TABS = 0; +const sal_uInt32 AX_TABSTRIP_BUTTONS = 1; +const sal_uInt32 AX_TABSTRIP_NONE = 2; + const sal_uInt32 AX_CONTAINER_ENABLED = 0x00000004; const sal_uInt32 AX_CONTAINER_HASDESIGNEXT = 0x00004000; const sal_uInt32 AX_CONTAINER_NOCLASSTABLE = 0x00008000; @@ -231,14 +236,6 @@ ControlConverter::~ControlConverter() // Generic conversion --------------------------------------------------------- -void ControlConverter::convertSize( PropertyMap& rPropMap, const AxPairData& rSize ) const -{ - // size is given in 1/100 mm, UNO needs AppFont units - Size aAppFontSize = mrGraphicHelper.convertHmmToAppFont( Size( rSize.first, rSize.second ) ); - rPropMap.setProperty( PROP_Width, aAppFontSize.Width ); - rPropMap.setProperty( PROP_Height, aAppFontSize.Height ); -} - void ControlConverter::convertPosition( PropertyMap& rPropMap, const AxPairData& rPos ) const { // position is given in 1/100 mm, UNO needs AppFont units @@ -247,6 +244,14 @@ void ControlConverter::convertPosition( PropertyMap& rPropMap, const AxPairData& rPropMap.setProperty( PROP_PositionY, aAppFontPos.Y ); } +void ControlConverter::convertSize( PropertyMap& rPropMap, const AxPairData& rSize ) const +{ + // size is given in 1/100 mm, UNO needs AppFont units + Size aAppFontSize = mrGraphicHelper.convertHmmToAppFont( Size( rSize.first, rSize.second ) ); + rPropMap.setProperty( PROP_Width, aAppFontSize.Width ); + rPropMap.setProperty( PROP_Height, aAppFontSize.Height ); +} + void ControlConverter::convertColor( PropertyMap& rPropMap, sal_Int32 nPropId, sal_uInt32 nOleColor ) const { rPropMap.setProperty( nPropId, OleHelper::decodeOleColor( mrGraphicHelper, nOleColor, mbDefaultColorBgr ) ); @@ -687,11 +692,11 @@ void AxFontDataModel::importProperty( sal_Int32 nPropId, const OUString& rValue { switch( nPropId ) { - case XML_FontName: maFontData.maFontName = rValue; break; - case XML_FontEffects: maFontData.mnFontEffects = AttributeList::decodeUnsigned( rValue ); break; - case XML_FontHeight: maFontData.mnFontHeight = AttributeList::decodeInteger( rValue ); break; - case XML_FontCharSet: maFontData.mnFontCharSet = AttributeList::decodeInteger( rValue ); break; - case XML_ParagraphAlign: maFontData.mnHorAlign = AttributeList::decodeInteger( rValue ); break; + case XML_FontName: maFontData.maFontName = rValue; break; + case XML_FontEffects: maFontData.mnFontEffects = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_FontHeight: maFontData.mnFontHeight = AttributeConversion::decodeInteger( rValue ); break; + case XML_FontCharSet: maFontData.mnFontCharSet = AttributeConversion::decodeInteger( rValue ); break; + case XML_ParagraphAlign: maFontData.mnHorAlign = AttributeConversion::decodeInteger( rValue ); break; default: AxControlModelBase::importProperty( nPropId, rValue ); } } @@ -757,12 +762,12 @@ void AxCommandButtonModel::importProperty( sal_Int32 nPropId, const OUString& rV { switch( nPropId ) { - case XML_Caption: maCaption = rValue; break; - case XML_ForeColor: mnTextColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BackColor: mnBackColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; - case XML_PicturePosition: mnPicturePos = AttributeList::decodeUnsigned( rValue ); break; - case XML_TakeFocusOnClick: mbFocusOnClick = AttributeList::decodeInteger( rValue ) != 0; break; + case XML_Caption: maCaption = rValue; break; + case XML_ForeColor: mnTextColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_PicturePosition: mnPicturePos = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_TakeFocusOnClick: mbFocusOnClick = AttributeConversion::decodeInteger( rValue ) != 0; break; default: AxFontDataModel::importProperty( nPropId, rValue ); } } @@ -828,12 +833,12 @@ void AxLabelModel::importProperty( sal_Int32 nPropId, const OUString& rValue ) switch( nPropId ) { case XML_Caption: maCaption = rValue; break; - case XML_ForeColor: mnTextColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BackColor: mnBackColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; - case XML_BorderColor: mnBorderColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BorderStyle: mnBorderStyle = AttributeList::decodeInteger( rValue ); break; - case XML_SpecialEffect: mnSpecialEffect = AttributeList::decodeInteger( rValue ); break; + case XML_ForeColor: mnTextColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BorderColor: mnBorderColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BorderStyle: mnBorderStyle = AttributeConversion::decodeInteger( rValue ); break; + case XML_SpecialEffect: mnSpecialEffect = AttributeConversion::decodeInteger( rValue ); break; default: AxFontDataModel::importProperty( nPropId, rValue ); } } @@ -892,14 +897,14 @@ void AxImageModel::importProperty( sal_Int32 nPropId, const OUString& rValue ) { switch( nPropId ) { - case XML_BackColor: mnBackColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; - case XML_BorderColor: mnBorderColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BorderStyle: mnBorderStyle = AttributeList::decodeInteger( rValue ); break; - case XML_SpecialEffect: mnSpecialEffect = AttributeList::decodeInteger( rValue ); break; - case XML_SizeMode: mnPicSizeMode = AttributeList::decodeInteger( rValue ); break; - case XML_PictureAlignment: mnPicAlign = AttributeList::decodeInteger( rValue ); break; - case XML_PictureTiling: mbPicTiling = AttributeList::decodeInteger( rValue ) != 0; break; + case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BorderColor: mnBorderColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BorderStyle: mnBorderStyle = AttributeConversion::decodeInteger( rValue ); break; + case XML_SpecialEffect: mnSpecialEffect = AttributeConversion::decodeInteger( rValue ); break; + case XML_SizeMode: mnPicSizeMode = AttributeConversion::decodeInteger( rValue ); break; + case XML_PictureAlignment: mnPicAlign = AttributeConversion::decodeInteger( rValue ); break; + case XML_PictureTiling: mbPicTiling = AttributeConversion::decodeInteger( rValue ) != 0; break; default: AxControlModelBase::importProperty( nPropId, rValue ); } } @@ -973,24 +978,24 @@ void AxMorphDataModelBase::importProperty( sal_Int32 nPropId, const OUString& rV { switch( nPropId ) { - case XML_Caption: maCaption = rValue; break; - case XML_Value: maValue = rValue; break; - case XML_GroupName: maGroupName = rValue; break; - case XML_ForeColor: mnTextColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BackColor: mnBackColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; - case XML_PicturePosition: mnPicturePos = AttributeList::decodeUnsigned( rValue ); break; - case XML_BorderColor: mnBorderColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BorderStyle: mnBorderStyle = AttributeList::decodeInteger( rValue ); break; - case XML_SpecialEffect: mnSpecialEffect = AttributeList::decodeInteger( rValue ); break; - case XML_DisplayStyle: mnDisplayStyle = AttributeList::decodeInteger( rValue ); break; - case XML_MultiSelect: mnMultiSelect = AttributeList::decodeInteger( rValue ); break; - case XML_ScrollBars: mnScrollBars = AttributeList::decodeInteger( rValue ); break; - case XML_MatchEntry: mnMatchEntry = AttributeList::decodeInteger( rValue ); break; - case XML_ShowDropButtonWhen: mnShowDropButton = AttributeList::decodeInteger( rValue ); break; - case XML_MaxLength: mnMaxLength = AttributeList::decodeInteger( rValue ); break; - case XML_PasswordChar: mnPasswordChar = AttributeList::decodeInteger( rValue ); break; - case XML_ListRows: mnListRows = AttributeList::decodeInteger( rValue ); break; + case XML_Caption: maCaption = rValue; break; + case XML_Value: maValue = rValue; break; + case XML_GroupName: maGroupName = rValue; break; + case XML_ForeColor: mnTextColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_PicturePosition: mnPicturePos = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BorderColor: mnBorderColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BorderStyle: mnBorderStyle = AttributeConversion::decodeInteger( rValue ); break; + case XML_SpecialEffect: mnSpecialEffect = AttributeConversion::decodeInteger( rValue ); break; + case XML_DisplayStyle: mnDisplayStyle = AttributeConversion::decodeInteger( rValue ); break; + case XML_MultiSelect: mnMultiSelect = AttributeConversion::decodeInteger( rValue ); break; + case XML_ScrollBars: mnScrollBars = AttributeConversion::decodeInteger( rValue ); break; + case XML_MatchEntry: mnMatchEntry = AttributeConversion::decodeInteger( rValue ); break; + case XML_ShowDropButtonWhen: mnShowDropButton = AttributeConversion::decodeInteger( rValue );break; + case XML_MaxLength: mnMaxLength = AttributeConversion::decodeInteger( rValue ); break; + case XML_PasswordChar: mnPasswordChar = AttributeConversion::decodeInteger( rValue ); break; + case XML_ListRows: mnListRows = AttributeConversion::decodeInteger( rValue ); break; default: AxFontDataModel::importProperty( nPropId, rValue ); } } @@ -1225,15 +1230,15 @@ void AxSpinButtonModel::importProperty( sal_Int32 nPropId, const OUString& rValu { switch( nPropId ) { - case XML_ForeColor: mnArrowColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BackColor: mnBackColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; - case XML_Orientation: mnOrientation = AttributeList::decodeInteger( rValue ); break; - case XML_Min: mnMin = AttributeList::decodeInteger( rValue ); break; - case XML_Max: mnMax = AttributeList::decodeInteger( rValue ); break; - case XML_Position: mnPosition = AttributeList::decodeInteger( rValue ); break; - case XML_SmallChange: mnSmallChange = AttributeList::decodeInteger( rValue ); break; - case XML_Delay: mnDelay = AttributeList::decodeInteger( rValue ); break; + case XML_ForeColor: mnArrowColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_Orientation: mnOrientation = AttributeConversion::decodeInteger( rValue ); break; + case XML_Min: mnMin = AttributeConversion::decodeInteger( rValue ); break; + case XML_Max: mnMax = AttributeConversion::decodeInteger( rValue ); break; + case XML_Position: mnPosition = AttributeConversion::decodeInteger( rValue ); break; + case XML_SmallChange: mnSmallChange = AttributeConversion::decodeInteger( rValue ); break; + case XML_Delay: mnDelay = AttributeConversion::decodeInteger( rValue ); break; default: AxControlModelBase::importProperty( nPropId, rValue ); } } @@ -1303,17 +1308,17 @@ void AxScrollBarModel::importProperty( sal_Int32 nPropId, const OUString& rValue { switch( nPropId ) { - case XML_ForeColor: mnArrowColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_BackColor: mnBackColor = AttributeList::decodeUnsigned( rValue ); break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; - case XML_Orientation: mnOrientation = AttributeList::decodeInteger( rValue ); break; - case XML_ProportionalThumb: mnPropThumb = AttributeList::decodeInteger( rValue ); break; - case XML_Min: mnMin = AttributeList::decodeInteger( rValue ); break; - case XML_Max: mnMax = AttributeList::decodeInteger( rValue ); break; - case XML_Position: mnPosition = AttributeList::decodeInteger( rValue ); break; - case XML_SmallChange: mnSmallChange = AttributeList::decodeInteger( rValue ); break; - case XML_LargeChange: mnLargeChange = AttributeList::decodeInteger( rValue ); break; - case XML_Delay: mnDelay = AttributeList::decodeInteger( rValue ); break; + case XML_ForeColor: mnArrowColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_BackColor: mnBackColor = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; + case XML_Orientation: mnOrientation = AttributeConversion::decodeInteger( rValue ); break; + case XML_ProportionalThumb: mnPropThumb = AttributeConversion::decodeInteger( rValue ); break; + case XML_Min: mnMin = AttributeConversion::decodeInteger( rValue ); break; + case XML_Max: mnMax = AttributeConversion::decodeInteger( rValue ); break; + case XML_Position: mnPosition = AttributeConversion::decodeInteger( rValue ); break; + case XML_SmallChange: mnSmallChange = AttributeConversion::decodeInteger( rValue ); break; + case XML_LargeChange: mnLargeChange = AttributeConversion::decodeInteger( rValue ); break; + case XML_Delay: mnDelay = AttributeConversion::decodeInteger( rValue ); break; default: AxControlModelBase::importProperty( nPropId, rValue ); } } @@ -1362,7 +1367,69 @@ void AxScrollBarModel::convertProperties( PropertyMap& rPropMap, const ControlCo // ============================================================================ -AxContainerModelBase::AxContainerModelBase() : +AxTabStripModel::AxTabStripModel() : + AxFontDataModel( false ), // no support for Align property + mnBackColor( AX_SYSCOLOR_BUTTONFACE ), + mnTextColor( AX_SYSCOLOR_BUTTONTEXT ), + mnFlags( AX_TABSTRIP_DEFFLAGS ), + mnSelectedTab( -1 ), + mnTabStyle( AX_TABSTRIP_TABS ), + mnTabFlagCount( 0 ) +{ +} + +bool AxTabStripModel::importBinaryModel( BinaryInputStream& rInStrm ) +{ + AxBinaryPropertyReader aReader( rInStrm ); + aReader.readIntProperty< sal_Int32 >( mnSelectedTab ); + aReader.readIntProperty< sal_uInt32 >( mnBackColor ); + aReader.readIntProperty< sal_uInt32 >( mnTextColor ); + aReader.skipUndefinedProperty(); + aReader.readPairProperty( maSize ); + aReader.readStringArrayProperty( maCaptions ); + aReader.skipIntProperty< sal_uInt8 >(); // mouse pointer + aReader.skipUndefinedProperty(); + aReader.skipIntProperty< sal_uInt32 >(); // tab orientation + aReader.readIntProperty< sal_uInt32 >( mnTabStyle ); + aReader.skipBoolProperty(); // multiple rows + aReader.skipIntProperty< sal_uInt32 >(); // fixed width + aReader.skipIntProperty< sal_uInt32 >(); // fixed height + aReader.skipBoolProperty(); // tooltips + aReader.skipUndefinedProperty(); + aReader.skipStringArrayProperty(); // tooltip strings + aReader.skipUndefinedProperty(); + aReader.skipStringArrayProperty(); // tab names + aReader.readIntProperty< sal_uInt32 >( mnFlags ); + aReader.skipBoolProperty(); // new version + aReader.skipIntProperty< sal_uInt32 >(); // tabs allocated + aReader.skipStringArrayProperty(); // tags + aReader.readIntProperty< sal_uInt32 >( mnTabFlagCount ); + aReader.skipStringArrayProperty(); // accelerators + aReader.skipPictureProperty(); // mouse icon + return aReader.finalizeImport() && AxFontDataModel::importBinaryModel( rInStrm ); +} + +ApiControlType AxTabStripModel::getControlType() const +{ + return API_CONTROL_TABSTRIP; +} + +void AxTabStripModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const +{ + rPropMap.setProperty( PROP_Decoration, mnTabStyle != AX_TABSTRIP_NONE ); + rPropMap.setProperty( PROP_MultiPageValue, mnSelectedTab ); + rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor ); + AxFontDataModel::convertProperties( rPropMap, rConv ); +} + +OUString AxTabStripModel::getCaption( sal_Int32 nIndex ) const +{ + return ContainerHelper::getVectorElement( maCaptions, nIndex, OUString() ); +} + +// ============================================================================ + +AxContainerModelBase::AxContainerModelBase( bool bFontSupport ) : AxFontDataModel( false ), // no support for Align property maLogicalSize( AX_CONTAINER_DEFWIDTH, AX_CONTAINER_DEFHEIGHT ), maScrollPos( 0, 0 ), @@ -1376,7 +1443,8 @@ AxContainerModelBase::AxContainerModelBase() : mnSpecialEffect( AX_SPECIALEFFECT_FLAT ), mnPicAlign( AX_PICALIGN_CENTER ), mnPicSizeMode( AX_PICSIZE_CLIP ), - mbPicTiling( false ) + mbPicTiling( false ), + mbFontSupport( bFontSupport ) { setAwtModelMode(); // different default size for frame @@ -1423,6 +1491,15 @@ bool AxContainerModelBase::importBinaryModel( BinaryInputStream& rInStrm ) return aReader.finalizeImport(); } +void AxContainerModelBase::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const +{ + if( mbFontSupport ) + { + rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor ); + AxFontDataModel::convertProperties( rPropMap, rConv ); + } +} + bool AxContainerModelBase::importClassTable( BinaryInputStream& rInStrm, AxClassTable& orClassTable ) { bool bValid = true; @@ -1457,7 +1534,8 @@ bool AxContainerModelBase::importClassTable( BinaryInputStream& rInStrm, AxClass // ============================================================================ -AxFrameModel::AxFrameModel() +AxFrameModel::AxFrameModel() : + AxContainerModelBase( true ) { } @@ -1475,6 +1553,49 @@ void AxFrameModel::convertProperties( PropertyMap& rPropMap, const ControlConver // ============================================================================ +AxFormPageModel::AxFormPageModel() +{ +} + +ApiControlType AxFormPageModel::getControlType() const +{ + return API_CONTROL_PAGE; +} + +void AxFormPageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const +{ + rPropMap.setProperty( PROP_Title, maCaption ); + rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) ); + rConv.convertColor( rPropMap, PROP_BackgroundColor, mnBackColor ); + AxContainerModelBase::convertProperties( rPropMap, rConv ); +} + +// ============================================================================ + +AxMultiPageModel::AxMultiPageModel() +{ +} + +ApiControlType AxMultiPageModel::getControlType() const +{ + return API_CONTROL_MULTIPAGE; +} + +void AxMultiPageModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const +{ + rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_CONTAINER_ENABLED ) ); + if( mxTabStrip.get() ) + mxTabStrip->convertProperties( rPropMap, rConv ); + AxContainerModelBase::convertProperties( rPropMap, rConv ); +} + +void AxMultiPageModel::setTabStripModel( const AxTabStripModelRef& rxTabStrip ) +{ + mxTabStrip = rxTabStrip; +} + +// ============================================================================ + AxUserFormModel::AxUserFormModel() { } diff --git a/oox/source/ole/vbacontrol.cxx b/oox/source/ole/vbacontrol.cxx index b43e8289a592..6ea28f424a83 100755 --- a/oox/source/ole/vbacontrol.cxx +++ b/oox/source/ole/vbacontrol.cxx @@ -198,9 +198,9 @@ void VbaSiteModel::importProperty( sal_Int32 nPropId, const OUString& rValue ) { switch( nPropId ) { - case XML_Name: maName = rValue; break; - case XML_Tag: maTag = rValue; break; - case XML_VariousPropertyBits: mnFlags = AttributeList::decodeUnsigned( rValue ); break; + case XML_Name: maName = rValue; break; + case XML_Tag: maTag = rValue; break; + case XML_VariousPropertyBits: mnFlags = AttributeConversion::decodeUnsigned( rValue ); break; } } @@ -231,6 +231,11 @@ void VbaSiteModel::moveRelative( const AxPairData& rDistance ) maPos.second += rDistance.second; } +bool VbaSiteModel::isVisible() const +{ + return getFlag( mnFlags, VBA_SITE_VISIBLE ); +} + bool VbaSiteModel::isContainer() const { return !getFlag( mnFlags, VBA_SITE_OSTREAM ); @@ -326,7 +331,7 @@ void VbaSiteModel::convertProperties( PropertyMap& rPropMap, if( (0 <= nCtrlIndex) && (nCtrlIndex <= SAL_MAX_INT16) ) rPropMap.setProperty( PROP_TabIndex, static_cast< sal_Int16 >( nCtrlIndex ) ); // progress bar and group box support TabIndex, but not Tabstop... - if( (eCtrlType != API_CONTROL_PROGRESSBAR) && (eCtrlType != API_CONTROL_GROUPBOX) ) + if( (eCtrlType != API_CONTROL_PROGRESSBAR) && (eCtrlType != API_CONTROL_GROUPBOX) && (eCtrlType != API_CONTROL_FRAME) && (eCtrlType != API_CONTROL_PAGE) ) rPropMap.setProperty( PROP_Tabstop, getFlag( mnFlags, VBA_SITE_TABSTOP ) ); rConv.convertPosition( rPropMap, maPos ); } @@ -367,6 +372,11 @@ OUString VbaFormControl::getControlName() const return mxSiteModel.get() ? mxSiteModel->getName() : OUString(); } +sal_Int32 VbaFormControl::getControlId() const +{ + return mxSiteModel.get() ? mxSiteModel->getId() : -1; +} + void VbaFormControl::createAndConvert( sal_Int32 nCtrlIndex, const Reference< XNameContainer >& rxParentNC, const ControlConverter& rConv ) const { diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx index 39ad52316a92..d60629b4481b 100644 --- a/oox/source/ppt/pptimport.cxx +++ b/oox/source/ppt/pptimport.cxx @@ -163,7 +163,7 @@ private: }; PptGraphicHelper::PptGraphicHelper( const PowerPointImport& rFilter ) : - GraphicHelper( rFilter.getGlobalFactory(), rFilter.getTargetFrame() ), + GraphicHelper( rFilter.getGlobalFactory(), rFilter.getTargetFrame(), rFilter.getStorage() ), mrFilter( rFilter ) { } diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx index 05734b65e2a7..e253d43e56e7 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -31,11 +31,6 @@ #include "oox/vml/vmlshapecontainer.hxx" #include "tokens.hxx" -#if DEBUG -#include <iostream> -using namespace std; -#endif - namespace oox { namespace shape { using namespace ::com::sun::star; @@ -93,9 +88,6 @@ ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element ) uno::Reference<xml::sax::XFastContextHandler> ShapeContextHandler::getDrawingShapeContext() { -#if DEBUG - clog << "ShapeContextHandler::getDrawingShapeContext" << endl; -#endif if (!mxDrawingFragmentHandler.is()) { mpDrawing.reset( new oox::vml::Drawing( *mxFilterBase, mxDrawPage, oox::vml::VMLDRAWING_WORD ) ); @@ -186,9 +178,6 @@ ShapeContextHandler::createFastChildContext const uno::Reference< xml::sax::XFastAttributeList > & Attribs) throw (uno::RuntimeException, xml::sax::SAXException) { -#if DEBUG - clog << "ShapeContextHandler::createFastChildContext" << endl; -#endif uno::Reference< xml::sax::XFastContextHandler > xResult; uno::Reference< xml::sax::XFastContextHandler > xContextHandler(getContextHandler()); @@ -243,6 +232,7 @@ ShapeContextHandler::getShape() throw (uno::RuntimeException) { mpShape->addShape(*mxFilterBase, mpThemePtr.get(), xShapes); xResult.set(mpShape->getXShape()); + mxGraphicShapeContext.clear( ); } } diff --git a/oox/source/token/makefile.mk b/oox/source/token/makefile.mk index 3c2e9201ea33..7884c375fde6 100644 --- a/oox/source/token/makefile.mk +++ b/oox/source/token/makefile.mk @@ -51,6 +51,7 @@ $(MISC)$/tokens.gperf $(INCCOM)$/tokenwords.inc $(INCCOM)$/tokens.hxx $(INCCOM)$ @@noop $(assign do_phony:=.PHONY) $(MISC)$/do_tokens $(do_phony) : tokens.txt gentoken.pl $(MISC)$/tokens.gperf $(INCCOM)$/tokenwords.inc $(INCCOM)$/tokens.hxx + @@-$(RM) $@ $(PERL) gentoken.pl tokens.txt $(INCCOM)$/tokens.hxx $(INCCOM)$/tokenwords.inc $(MISC)$/tokens.gperf && $(TOUCH) $@ $(INCCOM)$/oox: @@ -60,6 +61,7 @@ $(INCCOM)$/oox$/core: $(INCCOM)$/oox $(MKDIR) $(INCCOM)$/oox$/core $(MISC)$/do_namespaces $(do_phony) : namespaces.txt gennamespaces.pl + @@-$(RM) $@ $(MKDIRHIER) $(INCCOM)$/oox$/core $(PERL) gennamespaces.pl namespaces.txt $(INCCOM)$/oox$/core$/namespaces.hxx && $(TOUCH) $@ @@ -69,7 +71,8 @@ $(INCCOM)$/tokens.inc : $(MISC)$/tokens.gperf $(MISC)$/do_tokens $(SLO)$/tokenmap.obj : $(INCCOM)$/tokens.inc $(INCCOM)$/tokenwords.inc $(INCCOM)$/tokens.hxx $(INCCOM)$/oox$/core$/namespaces.hxx $(MISC)$/do_tokens $(MISC)$/do_namespaces $(MISC)$/do_properties $(do_phony) : properties.txt genproperties.pl $(INCCOM)$/properties.hxx $(INCCOM)$/propertywords.inc - $(PERL) genproperties.pl properties.txt $(INCCOM)$/properties.hxx $(INCCOM)$/propertywords.inc && $(TOUCH) $@ + @@-$(RM) $@ + $(PERL) genproperties.pl properties.txt $(INCCOM)$/properties.hxx $(INCCOM)$/propertywords.inc && $(TOUCH) $@ $(SLO)$/propertylist.obj : $(INCCOM)$/propertywords.inc $(INCCOM)$/properties.hxx $(MISC)$/do_properties diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 2b32b0a14d91..8244a298956a 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -103,6 +103,7 @@ D3DScenePerspective D3DSceneShadeMode DDELinks DatabaseRanges +Decoration DefaultContext DefaultScrollValue DefaultSpinValue @@ -250,6 +251,7 @@ LineStyle LineTransparence LineWidth LinkURL +LoadReadonly LookUpLabels MajorTickmarks MarkPosition @@ -259,7 +261,9 @@ MediaType MinorTickmarks MissingValueTreatment Model +ModifyPasswordHash MultiLine +MultiPageValue MultiSelection Name NamedRanges @@ -394,6 +398,7 @@ Suffix SwapXAndYAxis Symbol SymbolColor +TabColor TabIndex TableBorder TableLayout @@ -449,7 +454,6 @@ VisualEffect Weight WhiteDay Width -WriteProtectionPassword WritingMode ZoomType ZoomValue diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index 9a5f4451ec04..1cc74c32aa2d 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -39,6 +39,7 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::awt::Rectangle; using ::com::sun::star::awt::XControlModel; using ::com::sun::star::drawing::XDrawPage; +using ::com::sun::star::drawing::XShape; using ::com::sun::star::drawing::XShapes; using ::oox::core::XmlFilterBase; @@ -155,6 +156,10 @@ void Drawing::convertControlClientData( const Reference< XControlModel >& /*rxCt { } +void Drawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& /*rShapeRect*/ ) +{ +} + // ============================================================================ } // namespace vml diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index aae5b5c40556..333df72bbaf7 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -50,6 +50,7 @@ DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragm Reference< XInputStream > DrawingFragment::openFragmentStream() const { + // #i104719# create an input stream that preprocesses the VML data return new InputStream( FragmentHandler2::openFragmentStream() ); } diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index 6baea708c8a2..827930c22496 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -470,6 +470,7 @@ void FillModel::assignUsed( const FillModel& rSource ) moFocus.assignIfUsed( rSource.moFocus ); moFocusPos.assignIfUsed( rSource.moFocusPos ); moFocusSize.assignIfUsed( rSource.moFocusSize ); + moBitmapPath.assignIfUsed( rSource.moBitmapPath ); moRotate.assignIfUsed( rSource.moRotate ); } @@ -561,6 +562,23 @@ void FillModel::pushToPropMap( PropertyMap& rPropMap, } break; + case XML_pattern: + case XML_tile: + case XML_frame: + { + if( moBitmapPath.has() && moBitmapPath.get().getLength() > 0 ) + { + aFillProps.maBlipProps.mxGraphic = rGraphicHelper.importEmbeddedGraphic( moBitmapPath.get() ); + if( aFillProps.maBlipProps.mxGraphic.is() ) + { + aFillProps.moFillType = XML_blipFill; + aFillProps.maBlipProps.moBitmapMode = (nFillType == XML_frame) ? XML_stretch : XML_tile; + break; // do not break if bitmap is missing, but run to XML_solid instead + } + } + } + // run-through to XML_solid in case of missing bitmap path intended! + case XML_solid: default: { diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx index d80058c8f3e0..a6d50e193bc4 100644 --- a/oox/source/vml/vmlinputstream.cxx +++ b/oox/source/vml/vmlinputstream.cxx @@ -26,9 +26,13 @@ ************************************************************************/ #include "oox/vml/vmlinputstream.hxx" -#include <algorithm> -#include <string.h> +#include <map> +#include <rtl/strbuf.hxx> +#include <rtl/strbuf.hxx> +#include "oox/helper/helper.hxx" +using ::rtl::OString; +using ::rtl::OStringBuffer; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::io::XInputStream; @@ -38,6 +42,116 @@ namespace vml { // ============================================================================ +namespace { + +inline const sal_Char* lclFindCharacter( const sal_Char* pcBeg, const sal_Char* pcEnd, sal_Char cChar ) +{ + sal_Int32 nIndex = rtl_str_indexOfChar_WithLength( pcBeg, static_cast< sal_Int32 >( pcEnd - pcBeg ), cChar ); + return (nIndex < 0) ? pcEnd : (pcBeg + nIndex); +} + +inline bool lclIsWhiteSpace( sal_Char cChar ) +{ + return (cChar == ' ') || (cChar == '\t') || (cChar == '\n') || (cChar == '\r'); +} + +const sal_Char* lclFindWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + for( ; pcBeg < pcEnd; ++pcBeg ) + if( lclIsWhiteSpace( *pcBeg ) ) + return pcBeg; + return pcEnd; +} + +const sal_Char* lclFindNonWhiteSpace( const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + for( ; pcBeg < pcEnd; ++pcBeg ) + if( !lclIsWhiteSpace( *pcBeg ) ) + return pcBeg; + return pcEnd; +} + +const sal_Char* lclTrimWhiteSpaceFromEnd( const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + while( (pcBeg < pcEnd) && lclIsWhiteSpace( pcEnd[ -1 ] ) ) + --pcEnd; + return pcEnd; +} + +inline void lclAppendToBuffer( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + rBuffer.append( pcBeg, static_cast< sal_Int32 >( pcEnd - pcBeg ) ); +} + +// ---------------------------------------------------------------------------- + +void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + /* Map attribute names to char-pointer of all attributes. This map is used + to find multiple occurences of attributes with the same name. The + mapped pointers are used as map key in the next map below. */ + typedef ::std::map< OString, const sal_Char* > AttributeNameMap; + AttributeNameMap aAttributeNames; + + /* Map the char-pointers of all attributes to the full attribute definition + string. This preserves the original order of the used attributes. */ + typedef ::std::map< const sal_Char*, OString > AttributeDataMap; + AttributeDataMap aAttributes; + + bool bOk = true; + const sal_Char* pcNameBeg = pcBeg; + while( bOk && (pcNameBeg < pcEnd) ) + { + // pcNameBeg points to begin of attribute name, find equality sign + const sal_Char* pcEqualSign = lclFindCharacter( pcNameBeg, pcEnd, '=' ); + if( (bOk = pcEqualSign < pcEnd) == true ) + { + // find end of attribute name (ignore whitespace between name and equality sign) + const sal_Char* pcNameEnd = lclTrimWhiteSpaceFromEnd( pcNameBeg, pcEqualSign ); + if( (bOk = pcNameBeg < pcNameEnd) == true ) + { + // find begin of attribute value (must be single or double quote) + const sal_Char* pcValueBeg = lclFindNonWhiteSpace( pcEqualSign + 1, pcEnd ); + if( (bOk = (pcValueBeg < pcEnd) && ((*pcValueBeg == '\'') || (*pcValueBeg == '"'))) == true ) + { + // find end of attribute value (matching quote character) + const sal_Char* pcValueEnd = lclFindCharacter( pcValueBeg + 1, pcEnd, *pcValueBeg ); + if( (bOk = pcValueEnd < pcEnd) == true ) + { + ++pcValueEnd; + OString aAttribName( pcNameBeg, static_cast< sal_Int32 >( pcNameEnd - pcNameBeg ) ); + OString aAttribData( pcNameBeg, static_cast< sal_Int32 >( pcValueEnd - pcNameBeg ) ); + // search for an existing attribute with the same name + AttributeNameMap::iterator aIt = aAttributeNames.find( aAttribName ); + // remove its definition from the data map + if( aIt != aAttributeNames.end() ) + aAttributes.erase( aIt->second ); + // insert the attribute into both maps + aAttributeNames[ aAttribName ] = pcNameBeg; + aAttributes[ pcNameBeg ] = aAttribData; + // continue with next attribute (skip whitespace after this attribute) + pcNameBeg = pcValueEnd; + if( (pcNameBeg < pcEnd) && ((bOk = lclIsWhiteSpace( *pcNameBeg )) == true) ) + pcNameBeg = lclFindNonWhiteSpace( pcNameBeg + 1, pcEnd ); + } + } + } + } + } + + // if no error has occured, build the resulting attribute list + if( bOk ) + for( AttributeDataMap::iterator aIt = aAttributes.begin(), aEnd = aAttributes.end(); aIt != aEnd; ++aIt ) + rBuffer.append( ' ' ).append( aIt->second ); + // on error, just append the complete passed string + else + lclAppendToBuffer( rBuffer, pcBeg, pcEnd ); +} + +} // namespace + +// ============================================================================ + StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInStrm ) { if( rxInStrm.is() ) try @@ -49,26 +163,101 @@ StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInS { } - // parse the data and eat all parser instructions that make expat sad if( maDataSeq.hasElements() ) { - sal_Char* pcBeg = reinterpret_cast< sal_Char* >( maDataSeq.getArray() ); - sal_Char* pcEnd = pcBeg + maDataSeq.getLength(); - sal_Char* pcCurr = pcBeg; + const OString aCDataOpen = CREATE_OSTRING( "<![CDATA[" ); + const OString aCDataClose = CREATE_OSTRING( "]]>" ); + + OStringBuffer aBuffer; + aBuffer.ensureCapacity( maDataSeq.getLength() + 256 ); + const sal_Char* pcCurr = reinterpret_cast< const sal_Char* >( maDataSeq.getConstArray() ); + const sal_Char* pcEnd = pcCurr + maDataSeq.getLength(); while( pcCurr < pcEnd ) { - pcCurr = ::std::find( pcCurr, pcEnd, '<' ); - sal_Char* pcClose = ::std::find( pcCurr, pcEnd, '>' ); - if( (pcCurr < pcEnd) && (pcClose < pcEnd) && (pcClose - pcCurr >= 5) && (pcCurr[ 1 ] == '!') && (pcCurr[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) + // look for the next opening angle bracket + const sal_Char* pcOpen = lclFindCharacter( pcCurr, pcEnd, '<' ); + // copy all characters from current position to opening bracket + lclAppendToBuffer( aBuffer, pcCurr, pcOpen ); + + // nothing to do if no opening bracket has been found + if( pcOpen < pcEnd ) { - ++pcClose; - memmove( pcCurr, pcClose, pcEnd - pcClose ); - pcEnd -= (pcClose - pcCurr); + // string length from opening bracket to end + sal_Int32 nLengthToEnd = static_cast< sal_Int32 >( pcEnd - pcOpen ); + + // check for CDATA part, starting with '<![CDATA[' + if( rtl_str_compare_WithLength( pcOpen, nLengthToEnd, aCDataOpen.getStr(), aCDataOpen.getLength() ) == 0 ) + { + // search the position after the end tag ']]>' + sal_Int32 nClosePos = rtl_str_indexOfStr_WithLength( pcOpen, nLengthToEnd, aCDataClose.getStr(), aCDataClose.getLength() ); + pcCurr = (nClosePos < 0) ? pcEnd : (pcOpen + nClosePos + aCDataClose.getLength()); + // copy the entire CDATA part + lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); + } + + // no CDATA part - process the element starting at pcOpen + else + { + // look for the next closing angle bracket + const sal_Char* pcClose = lclFindCharacter( pcOpen + 1, pcEnd, '>' ); + // complete element found? + if( pcClose < pcEnd ) + { + // continue after closing bracket + pcCurr = pcClose + 1; + // length of entire element with angle brackets + sal_Int32 nElementLen = static_cast< sal_Int32 >( pcCurr - pcOpen ); + + // skip parser instructions: '<![...]>' + if( (nElementLen >= 5) && (pcOpen[ 1 ] == '!') && (pcOpen[ 2 ] == '[') && (pcClose[ -1 ] == ']') ) + { + // do nothing + } + + // replace '<br>' elements with '<br/>' elements + else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) + { + aBuffer.append( RTL_CONSTASCII_STRINGPARAM( "<br/>" ) ); + } + + // check start elements and empty elements for repeated attributes + else if( pcOpen[ 1 ] != '/' ) + { + // find positions of text content inside brackets, exclude '/' in '<emptyelement/>' + const sal_Char* pcContentBeg = pcOpen + 1; + bool bIsEmptyElement = pcClose[ -1 ] == '/'; + const sal_Char* pcContentEnd = bIsEmptyElement ? (pcClose - 1) : pcClose; + // append element name to buffer + const sal_Char* pcWhiteSpace = lclFindWhiteSpace( pcContentBeg, pcContentEnd ); + lclAppendToBuffer( aBuffer, pcOpen, pcWhiteSpace ); + // find begin of attributes, and process all attributes + const sal_Char* pcAttribBeg = lclFindNonWhiteSpace( pcWhiteSpace, pcContentEnd ); + if( pcAttribBeg < pcContentEnd ) + lclProcessAttribs( aBuffer, pcAttribBeg, pcContentEnd ); + // close the element + if( bIsEmptyElement ) + aBuffer.append( '/' ); + aBuffer.append( '>' ); + } + + // append end elements without further processing + else + { + lclAppendToBuffer( aBuffer, pcOpen, pcCurr ); + } + } + else + { + // no complete element found, copy all from opening bracket to end + lclAppendToBuffer( aBuffer, pcOpen, pcEnd ); + pcCurr = pcEnd; + } + } } - else - pcCurr = pcClose; } - maDataSeq.realloc( static_cast< sal_Int32 >( pcEnd - pcBeg ) ); + + // set the final data sequence + maDataSeq = ::comphelper::ByteSequence( reinterpret_cast< const sal_Int8* >( aBuffer.getStr() ), aBuffer.getLength() ); } } diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 40b3e9952b43..d557a7f50354 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -36,6 +36,7 @@ #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/graphic/XGraphic.hpp> #include "properties.hxx" +#include "oox/helper/graphichelper.hxx" #include "oox/helper/propertymap.hxx" #include "oox/helper/propertyset.hxx" #include "oox/core/xmlfilterbase.hxx" @@ -99,7 +100,7 @@ Reference< XShape > lclCreateXShape( const XmlFilterBase& rFilter, const OUStrin Reference< XShape > xShape; try { - Reference< XMultiServiceFactory > xFactory( rFilter.getModel(), UNO_QUERY_THROW ); + Reference< XMultiServiceFactory > xFactory( rFilter.getModelFactory(), UNO_SET_THROW ); xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); } catch( Exception& ) @@ -165,7 +166,7 @@ void ShapeTypeModel::assignUsed( const ShapeTypeModel& rSource ) // ---------------------------------------------------------------------------- -ShapeType::ShapeType( const Drawing& rDrawing ) : +ShapeType::ShapeType( Drawing& rDrawing ) : mrDrawing( rDrawing ) { } @@ -237,7 +238,7 @@ ShapeClientData& ShapeModel::createClientData() // ---------------------------------------------------------------------------- -ShapeBase::ShapeBase( const Drawing& rDrawing ) : +ShapeBase::ShapeBase( Drawing& rDrawing ) : ShapeType( rDrawing ) { } @@ -270,7 +271,14 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); // convert the shape, if the calculated rectangle is not empty if( ((aShapeRect.Width > 0) || (aShapeRect.Height > 0)) && rxShapes.is() ) + { xShape = implConvertAndInsert( rxShapes, aShapeRect ); + /* Notify the drawing that a new shape has been inserted (but not + for children of group shapes). For convenience, pass the + rectangle that contains position and size of the shape. */ + if( !pParentAnchor && xShape.is() ) + mrDrawing.notifyShapeInserted( xShape, aShapeRect ); + } } return xShape; } @@ -318,7 +326,7 @@ void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) con // ============================================================================ -SimpleShape::SimpleShape( const Drawing& rDrawing, const OUString& rService ) : +SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) : ShapeBase( rDrawing ), maService( rService ) { @@ -333,21 +341,21 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes // ============================================================================ -RectangleShape::RectangleShape( const Drawing& rDrawing ) : +RectangleShape::RectangleShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.RectangleShape" ) ) { } // ============================================================================ -EllipseShape::EllipseShape( const Drawing& rDrawing ) : +EllipseShape::EllipseShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.EllipseShape" ) ) { } // ============================================================================ -PolyLineShape::PolyLineShape( const Drawing& rDrawing ) : +PolyLineShape::PolyLineShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.PolyLineShape" ) ) { } @@ -372,7 +380,7 @@ Reference< XShape > PolyLineShape::implConvertAndInsert( const Reference< XShape // ============================================================================ -CustomShape::CustomShape( const Drawing& rDrawing ) : +CustomShape::CustomShape( Drawing& rDrawing ) : SimpleShape( rDrawing, CREATE_OUSTRING( "com.sun.star.drawing.CustomShape" ) ) { } @@ -397,7 +405,7 @@ Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes // ============================================================================ -ComplexShape::ComplexShape( const Drawing& rDrawing ) : +ComplexShape::ComplexShape( Drawing& rDrawing ) : CustomShape( rDrawing ) { } @@ -424,7 +432,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes // set the replacement graphic if( aGraphicPath.getLength() > 0 ) { - Reference< XGraphic > xGraphic = rFilter.importEmbeddedGraphic( aGraphicPath ); + Reference< XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath ); if( xGraphic.is() ) aOleProps[ PROP_Graphic ] <<= xGraphic; } @@ -471,7 +479,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes Reference< XShape > xShape = lclCreateAndInsertXShape( rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rShapeRect ); if( xShape.is() ) { - OUString aGraphicUrl = rFilter.importEmbeddedGraphicObject( aGraphicPath ); + OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath ); if( aGraphicUrl.getLength() > 0 ) { PropertySet aPropSet( xShape ); @@ -487,7 +495,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes // ============================================================================ -GroupShape::GroupShape( const Drawing& rDrawing ) : +GroupShape::GroupShape( Drawing& rDrawing ) : ShapeBase( rDrawing ), mxChildren( new ShapeContainer( rDrawing ) ) { diff --git a/oox/source/vml/vmlshapecontainer.cxx b/oox/source/vml/vmlshapecontainer.cxx index 8e36e4b0054e..a3bdfdb217d7 100644 --- a/oox/source/vml/vmlshapecontainer.cxx +++ b/oox/source/vml/vmlshapecontainer.cxx @@ -60,7 +60,7 @@ void lclMapShapesById( RefMap< OUString, ShapeType >& orMap, const RefVector< Sh // ============================================================================ -ShapeContainer::ShapeContainer( const Drawing& rDrawing ) : +ShapeContainer::ShapeContainer( Drawing& rDrawing ) : mrDrawing( rDrawing ) { } diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index 09aa19902366..ec7da1d4d900 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -44,9 +44,9 @@ namespace { /** Returns the boolean value from the specified VML attribute (if present). */ -OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nElement ) +OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nToken ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); if( oValue.has() ) return OptValue< bool >( ConversionHelper::decodeBool( oValue.get() ) ); return OptValue< bool >(); } @@ -54,18 +54,18 @@ OptValue< bool > lclDecodeBool( const AttributeList& rAttribs, sal_Int32 nElemen /** Returns the percentage value from the specified VML attribute (if present). The value will be normalized (1.0 is returned for 100%). */ -OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nElement, double fDefValue ) +OptValue< double > lclDecodePercent( const AttributeList& rAttribs, sal_Int32 nToken, double fDefValue ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); if( oValue.has() ) return OptValue< double >( ConversionHelper::decodePercent( oValue.get(), fDefValue ) ); return OptValue< double >(); } /** Returns the integer value pair from the specified VML attribute (if present). */ -OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nElement ) +OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int32 nToken ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); OptValue< Int32Pair > oRetValue; if( oValue.has() ) { @@ -78,9 +78,9 @@ OptValue< Int32Pair > lclDecodeInt32Pair( const AttributeList& rAttribs, sal_Int /** Returns the percentage pair from the specified VML attribute (if present). */ -OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nElement ) +OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_Int32 nToken ) { - OptValue< OUString > oValue = rAttribs.getString( nElement ); + OptValue< OUString > oValue = rAttribs.getString( nToken ); OptValue< DoublePair > oRetValue; if( oValue.has() ) { @@ -235,18 +235,26 @@ ContextHandlerRef ShapeTypeContext::onCreateContext( sal_Int32 nElement, const A mrTypeModel.maFillModel.moFocus = lclDecodePercent( rAttribs, XML_focus, 0.0 ); mrTypeModel.maFillModel.moFocusPos = lclDecodePercentPair( rAttribs, XML_focusposition ); mrTypeModel.maFillModel.moFocusSize = lclDecodePercentPair( rAttribs, XML_focussize ); + mrTypeModel.maFillModel.moBitmapPath = decodeFragmentPath( rAttribs, O_TOKEN( relid ) ); mrTypeModel.maFillModel.moRotate = lclDecodeBool( rAttribs, XML_rotate ); break; case VML_TOKEN( imagedata ): - OptValue< OUString > oGraphicRelId = rAttribs.getString( O_TOKEN( relid ) ); - if( oGraphicRelId.has() ) - mrTypeModel.moGraphicPath = getFragmentPathFromRelId( oGraphicRelId.get() ); + mrTypeModel.moGraphicPath = decodeFragmentPath( rAttribs, O_TOKEN( relid ) ); mrTypeModel.moGraphicTitle = rAttribs.getString( O_TOKEN( title ) ); break; } return 0; } +OptValue< OUString > ShapeTypeContext::decodeFragmentPath( const AttributeList& rAttribs, sal_Int32 nToken ) const +{ + OptValue< OUString > oFragmentPath; + OptValue< OUString > oRelId = rAttribs.getString( nToken ); + if( oRelId.has() ) + oFragmentPath = getFragmentPathFromRelId( oRelId.get() ); + return oFragmentPath; +} + void ShapeTypeContext::setStyle( const OUString& rStyle ) { sal_Int32 nIndex = 0; diff --git a/oox/source/xls/chartsheetfragment.cxx b/oox/source/xls/chartsheetfragment.cxx index 4980312900fd..287518584cc3 100644 --- a/oox/source/xls/chartsheetfragment.cxx +++ b/oox/source/xls/chartsheetfragment.cxx @@ -263,6 +263,7 @@ bool BiffChartsheetFragment::importFragment() case BIFF8: switch( nRecId ) { + case BIFF_ID_CODENAME: rWorksheetSett.importCodeName( mrStrm ); break; case BIFF_ID_HCENTER: rPageSett.importHorCenter( mrStrm ); break; case BIFF_ID_OBJECTPROTECT: rWorksheetSett.importObjectProtect( mrStrm ); break; case BIFF_ID_PICTURE: rPageSett.importPicture( mrStrm ); break; diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 28687ba92da7..172530692923 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -62,6 +62,7 @@ using ::com::sun::star::form::binding::XBindableValue; using ::com::sun::star::form::binding::XListEntrySink; using ::com::sun::star::form::binding::XListEntrySource; using ::com::sun::star::form::binding::XValueBinding; +using ::com::sun::star::drawing::XShape; using ::com::sun::star::table::CellAddress; using ::com::sun::star::table::CellRangeAddress; using ::oox::core::ContextHandlerRef; @@ -508,9 +509,13 @@ void OoxDrawingFragment::onEndElement( const OUString& rChars ) case XDR_TOKEN( twoCellAnchor ): if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() && mxAnchor->isValidAnchor() ) { - Rectangle aLoc = mxAnchor->calcEmuLocation( maEmuSheetSize ); - if( (aLoc.X >= 0) && (aLoc.Y >= 0) && (aLoc.Width >= 0) && (aLoc.Height >= 0) ) - mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aLoc ); + Rectangle aShapeRect = mxAnchor->calcEmuLocation( maEmuSheetSize ); + if( (aShapeRect.X >= 0) && (aShapeRect.Y >= 0) && (aShapeRect.Width >= 0) && (aShapeRect.Height >= 0) ) + { + mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, &aShapeRect ); + // collect all shape positions in the WorksheetHelper base class + extendShapeBoundingBox( aShapeRect ); + } } mxShape.reset(); mxAnchor.reset(); @@ -648,6 +653,12 @@ void VmlDrawing::convertControlClientData( const Reference< XControlModel >& rxC } } +void VmlDrawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& rShapeRect ) +{ + // collect all shape positions in the WorksheetHelper base class + extendShapeBoundingBox( rShapeRect ); +} + // ============================================================================ OoxVmlDrawingFragment::OoxVmlDrawingFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index b2e5ba0ee931..ea353bb48558 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -1262,6 +1262,11 @@ bool OpCodeProviderImpl::initFuncOpCode( FunctionInfo& orFuncInfo, const ApiToke maParserMap.push_back( aEntry ); } } + else + { + // ignore entries for functions unknown by Calc *and* by Excel + bIsValid = orFuncInfo.maOoxFuncName.getLength() == 0; + } } else if( orFuncInfo.mnBiffFuncId == BIFF_FUNC_EXTERNCALL ) { diff --git a/oox/source/xls/pagesettings.cxx b/oox/source/xls/pagesettings.cxx index c0b1011fdbcc..0a5ce05a37df 100644 --- a/oox/source/xls/pagesettings.cxx +++ b/oox/source/xls/pagesettings.cxx @@ -440,7 +440,7 @@ void PageSettings::importPictureData( const Relations& rRelations, const OUStrin { OUString aPicturePath = rRelations.getFragmentPathFromRelId( rRelId ); if( aPicturePath.getLength() > 0 ) - maModel.maGraphicUrl = getBaseFilter().importEmbeddedGraphicObject( aPicturePath ); + maModel.maGraphicUrl = getBaseFilter().getGraphicHelper().importEmbeddedGraphicObject( aPicturePath ); } // ============================================================================ diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 43c2f1b0b654..05e4c5bfe767 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -364,6 +364,10 @@ void OoxSheetDataContext::importCell( const AttributeList& rAttribs ) maCurrCell.mnXfId = rAttribs.getInteger( XML_s, -1 ); maCurrCell.mbShowPhonetic = rAttribs.getBool( XML_ph, false ); mxInlineStr.reset(); + + // update used area of the sheet + if( maCurrCell.mxCell.is() ) + extendUsedArea( maCurrCell.maAddress ); } void OoxSheetDataContext::importFormula( const AttributeList& rAttribs ) @@ -396,6 +400,10 @@ void OoxSheetDataContext::importCellHeader( RecordInputStream& rStrm, CellType e maCurrCell.mxCell = getCell( maCurrPos, &maCurrCell.maAddress ); maCurrCell.mnXfId = extractValue< sal_Int32 >( nXfId, 0, 24 ); maCurrCell.mbShowPhonetic = getFlag( nXfId, OOBIN_CELL_SHOWPHONETIC ); + + // update used area of the sheet + if( maCurrCell.mxCell.is() ) + extendUsedArea( maCurrCell.maAddress ); } void OoxSheetDataContext::importCellBool( RecordInputStream& rStrm, CellType eCellType ) @@ -701,6 +709,9 @@ void BiffSheetDataContext::setCurrCell( const BinAddress& rAddr ) { maCurrCell.reset(); maCurrCell.mxCell = getCell( rAddr, &maCurrCell.maAddress ); + // update used area of the sheet + if( maCurrCell.mxCell.is() ) + extendUsedArea( maCurrCell.maAddress ); } void BiffSheetDataContext::importXfId( bool bBiff2 ) diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx index b9a11b5104ea..5a149961c0e2 100644 --- a/oox/source/xls/stylesbuffer.cxx +++ b/oox/source/xls/stylesbuffer.cxx @@ -306,7 +306,7 @@ sal_Int32 lclReadRgbColor( BinaryInputStream& rStrm ) // ============================================================================ ExcelGraphicHelper::ExcelGraphicHelper( const WorkbookHelper& rHelper ) : - GraphicHelper( rHelper.getGlobalFactory(), rHelper.getBaseFilter().getTargetFrame() ), + GraphicHelper( rHelper.getGlobalFactory(), rHelper.getBaseFilter().getTargetFrame(), rHelper.getBaseFilter().getStorage() ), WorkbookHelper( rHelper ) { } diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx index 3d88e64dbb12..05dfa7bf9f96 100644 --- a/oox/source/xls/viewsettings.cxx +++ b/oox/source/xls/viewsettings.cxx @@ -26,11 +26,14 @@ ************************************************************************/ #include "oox/xls/viewsettings.hxx" +#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/awt/Size.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/container/XIndexContainer.hpp> #include <com/sun/star/document/XViewDataSupplier.hpp> #include <com/sun/star/text/WritingMode2.hpp> +#include <comphelper/mediadescriptor.hxx> #include "properties.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/containerhelper.hxx" @@ -38,22 +41,26 @@ #include "oox/helper/propertyset.hxx" #include "oox/helper/recordinputstream.hxx" #include "oox/core/filterbase.hxx" +#include "oox/xls/addressconverter.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/unitconverter.hxx" #include "oox/xls/workbooksettings.hxx" #include "oox/xls/worksheetbuffer.hxx" using ::rtl::OUString; -using ::com::sun::star::uno::Any; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::Exception; -using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::awt::Point; +using ::com::sun::star::awt::Size; using ::com::sun::star::container::XNameContainer; using ::com::sun::star::container::XIndexContainer; using ::com::sun::star::container::XIndexAccess; using ::com::sun::star::document::XViewDataSupplier; using ::com::sun::star::table::CellAddress; +using ::com::sun::star::table::CellRangeAddress; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::UNO_QUERY_THROW; using ::oox::core::FilterBase; namespace oox { @@ -622,7 +629,8 @@ WorkbookViewModel::WorkbookViewModel() : // ---------------------------------------------------------------------------- ViewSettings::ViewSettings( const WorkbookHelper& rHelper ) : - WorkbookHelper( rHelper ) + WorkbookHelper( rHelper ), + mbValidOleSize( false ) { } @@ -643,6 +651,12 @@ void ViewSettings::importWorkbookView( const AttributeList& rAttribs ) rModel.mbMinimized = rAttribs.getBool( XML_minimized, false ); } +void ViewSettings::importOleSize( const AttributeList& rAttribs ) +{ + OUString aRange = rAttribs.getString( XML_ref, OUString() ); + mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aRange, 0, true, false ); +} + void ViewSettings::importWorkbookView( RecordInputStream& rStrm ) { WorkbookViewModel& rModel = createWorkbookView(); @@ -655,6 +669,13 @@ void ViewSettings::importWorkbookView( RecordInputStream& rStrm ) rModel.mbMinimized = getFlag( nFlags, OOBIN_WBVIEW_MINIMIZED ); } +void ViewSettings::importOleSize( RecordInputStream& rStrm ) +{ + BinRange aBinRange; + rStrm >> aBinRange; + mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aBinRange, 0, true, false ); +} + void ViewSettings::importWindow1( BiffInputStream& rStrm ) { sal_uInt16 nWinX, nWinY, nWinWidth, nWinHeight; @@ -691,12 +712,25 @@ void ViewSettings::importWindow1( BiffInputStream& rStrm ) } } +void ViewSettings::importOleSize( BiffInputStream& rStrm ) +{ + rStrm.skip( 2 ); + BinRange aBinRange; + aBinRange.read( rStrm, false ); + mbValidOleSize = getAddressConverter().convertToCellRange( maOleSize, aBinRange, 0, true, false ); +} + void ViewSettings::setSheetViewSettings( sal_Int16 nSheet, const SheetViewModelRef& rxSheetView, const Any& rProperties ) { maSheetViews[ nSheet ] = rxSheetView; maSheetProps[ nSheet ] = rProperties; } +void ViewSettings::setSheetUsedArea( const CellRangeAddress& rUsedArea ) +{ + maSheetUsedAreas[ rUsedArea.Sheet ] = rUsedArea; +} + void ViewSettings::finalizeImport() { const WorksheetBuffer& rWorksheets = getWorksheets(); @@ -751,6 +785,31 @@ void ViewSettings::finalizeImport() { OSL_ENSURE( false, "ViewSettings::finalizeImport - cannot create document view settings" ); } + + /* Set visible area to be used if this document is an embedded OLE object. + #i44077# If a new OLE object is inserted from file, there is no OLESIZE + record in the Excel file. In this case, use the used area calculated + from file contents (used cells and drawing objects). */ + maOleSize.Sheet = nActiveSheet; + const CellRangeAddress* pVisibleArea = mbValidOleSize ? + &maOleSize : ContainerHelper::getMapElement( maSheetUsedAreas, nActiveSheet ); + if( pVisibleArea ) + { + // calculate the visible area in units of 1/100 mm + PropertySet aRangeProp( getCellRangeFromDoc( *pVisibleArea ) ); + Point aPos; + Size aSize; + if( aRangeProp.getProperty( aPos, PROP_Position ) && aRangeProp.getProperty( aSize, PROP_Size ) ) + { + // set the visible area as sequence of long at the media descriptor + Sequence< sal_Int32 > aWinExtent( 4 ); + aWinExtent[ 0 ] = aPos.X; + aWinExtent[ 1 ] = aPos.Y; + aWinExtent[ 2 ] = aPos.X + aSize.Width; + aWinExtent[ 3 ] = aPos.Y + aSize.Height; + getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "WinExtent" ) ] <<= aWinExtent; + } + } } sal_Int16 ViewSettings::getActiveCalcSheet() const @@ -771,4 +830,3 @@ WorkbookViewModel& ViewSettings::createWorkbookView() } // namespace xls } // namespace oox - diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index d64abf268008..6e43a32495be 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -105,6 +105,7 @@ ContextHandlerRef OoxWorkbookFragment::onCreateContext( sal_Int32 nElement, cons case XLS_TOKEN( fileSharing ): getWorkbookSettings().importFileSharing( rAttribs ); break; case XLS_TOKEN( workbookPr ): getWorkbookSettings().importWorkbookPr( rAttribs ); break; case XLS_TOKEN( calcPr ): getWorkbookSettings().importCalcPr( rAttribs ); break; + case XLS_TOKEN( oleSize ): getViewSettings().importOleSize( rAttribs ); break; } break; @@ -156,6 +157,7 @@ ContextHandlerRef OoxWorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, case OOBIN_ID_FILESHARING: getWorkbookSettings().importFileSharing( rStrm ); break; case OOBIN_ID_WORKBOOKPR: getWorkbookSettings().importWorkbookPr( rStrm ); break; case OOBIN_ID_CALCPR: getWorkbookSettings().importCalcPr( rStrm ); break; + case OOBIN_ID_OLESIZE: getViewSettings().importOleSize( rStrm ); break; case OOBIN_ID_DEFINEDNAME: getDefinedNames().importDefinedName( rStrm ); break; } break; @@ -565,6 +567,7 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break; case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break; case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; + case BIFF_ID_OLESIZE: rViewSett.importOleSize( mrStrm ); break; case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break; case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( mrStrm ); break; case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break; @@ -587,14 +590,15 @@ bool BiffWorkbookFragment::importGlobalsFragment( ISegmentProgressBar& rProgress case BIFF5_ID_FONT: rStyles.importFont( mrStrm ); break; case BIFF4_ID_FORMAT: rStyles.importFormat( mrStrm ); break; case BIFF_ID_HIDEOBJ: rWorkbookSett.importHideObj( mrStrm ); break; - case BIFF_ID_VBAPROJECT: bHasVbaProject = true; break; - case BIFF_ID_VBAPROJECTEMPTY: bEmptyVbaProject = true; break; + case BIFF_ID_OLESIZE: rViewSett.importOleSize( mrStrm ); break; case BIFF_ID_PALETTE: rStyles.importPalette( mrStrm ); break; case BIFF_ID_PIVOTCACHE: rPivotCaches.importPivotCacheRef( mrStrm ); break; case BIFF_ID_SHEET: rWorksheets.importSheet( mrStrm ); break; case BIFF_ID_SST: rSharedStrings.importSst( mrStrm ); break; case BIFF_ID_STYLE: rStyles.importStyle( mrStrm ); break; case BIFF_ID_USESELFS: rWorkbookSett.importUsesElfs( mrStrm ); break; + case BIFF_ID_VBAPROJECT: bHasVbaProject = true; break; + case BIFF_ID_VBAPROJECTEMPTY: bEmptyVbaProject = true; break; case BIFF_ID_XCT: bExtLinkRec = true; break; case BIFF5_ID_XF: rStyles.importXf( mrStrm ); break; } diff --git a/oox/source/xls/workbooksettings.cxx b/oox/source/xls/workbooksettings.cxx index 40d400da7757..51d60ebafe3b 100644 --- a/oox/source/xls/workbooksettings.cxx +++ b/oox/source/xls/workbooksettings.cxx @@ -26,9 +26,9 @@ ************************************************************************/ #include "oox/xls/workbooksettings.hxx" +#include <com/sun/star/sheet/XCalculatable.hpp> #include <com/sun/star/util/Date.hpp> #include <com/sun/star/util/XNumberFormatsSupplier.hpp> -#include <com/sun/star/sheet/XCalculatable.hpp> #include <comphelper/mediadescriptor.hxx> #include "properties.hxx" #include "oox/helper/attributelist.hxx" @@ -39,11 +39,16 @@ #include "oox/xls/unitconverter.hxx" using ::rtl::OUString; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::sheet::XCalculatable; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::util::Date; using ::com::sun::star::util::XNumberFormatsSupplier; -using ::com::sun::star::sheet::XCalculatable; +using ::comphelper::MediaDescriptor; using ::oox::core::CodecHelper; namespace oox { @@ -191,23 +196,6 @@ void WorkbookSettings::setSaveExtLinkValues( bool bSaveExtLinks ) maBookSettings.mbSaveExtLinkValues = bSaveExtLinks; } -void WorkbookSettings::importFileSharing( BiffInputStream& rStrm ) -{ - maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0; - rStrm >> maFileSharing.mnPasswordHash; - if( getBiff() == BIFF8 ) - { - sal_uInt16 nStrLen = rStrm.readuInt16(); - // there is no string flags field if string is empty - if( nStrLen > 0 ) - maFileSharing.maUserName = rStrm.readUniStringBody( nStrLen ); - } - else - { - maFileSharing.maUserName = rStrm.readByteStringUC( false, getTextEncoding() ); - } -} - void WorkbookSettings::importBookBool( BiffInputStream& rStrm ) { // value of 0 means save external values, value of 1 means strip external values @@ -241,6 +229,23 @@ void WorkbookSettings::importDelta( BiffInputStream& rStrm ) rStrm >> maCalcSettings.mfIterateDelta; } +void WorkbookSettings::importFileSharing( BiffInputStream& rStrm ) +{ + maFileSharing.mbRecommendReadOnly = rStrm.readuInt16() != 0; + rStrm >> maFileSharing.mnPasswordHash; + if( getBiff() == BIFF8 ) + { + sal_uInt16 nStrLen = rStrm.readuInt16(); + // there is no string flags field if string is empty + if( nStrLen > 0 ) + maFileSharing.maUserName = rStrm.readUniStringBody( nStrLen ); + } + else + { + maFileSharing.maUserName = rStrm.readByteStringUC( false, getTextEncoding() ); + } +} + void WorkbookSettings::importHideObj( BiffInputStream& rStrm ) { maBookSettings.setBinObjectMode( rStrm.readuInt16() ); @@ -293,10 +298,21 @@ void WorkbookSettings::finalizeImport() } // write protection - if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) ) + if( maFileSharing.mbRecommendReadOnly || (maFileSharing.mnPasswordHash != 0) ) try + { getBaseFilter().getMediaDescriptor()[ CREATE_OUSTRING( "ReadOnly" ) ] <<= true; - if( maFileSharing.mnPasswordHash != 0 ) - aPropSet.setProperty( PROP_WriteProtectionPassword, static_cast< sal_Int32 >( maFileSharing.mnPasswordHash ) ); + + Reference< XPropertySet > xDocumentSettings( getDocumentFactory()->createInstance( + CREATE_OUSTRING( "com.sun.star.document.Settings" ) ), UNO_QUERY_THROW ); + PropertySet aSettingsProp( xDocumentSettings ); + if( maFileSharing.mbRecommendReadOnly ) + aSettingsProp.setProperty( PROP_LoadReadonly, true ); +// if( maFileSharing.mnPasswordHash != 0 ) +// aSettingsProp.setProperty( PROP_ModifyPasswordHash, static_cast< sal_Int32 >( maFileSharing.mnPasswordHash ) ); + } + catch( Exception& ) + { + } // calculation settings Date aNullDate = getNullDate(); diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index 14cf80a91d52..bee58fdbaff3 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -514,7 +514,12 @@ void OoxWorksheetFragment::importDimension( const AttributeList& rAttribs ) { CellRangeAddress aRange; getAddressConverter().convertToCellRangeUnchecked( aRange, rAttribs.getString( XML_ref, OUString() ), getSheetIndex() ); - setDimension( aRange ); + /* OOXML stores the used area, if existing, or "A1" if the sheet is empty. + In case of "A1", the dimension at the WorksheetHelper object will not + be set. If the cell A1 exists, the used area will be updated while + importing the cell. */ + if( (aRange.EndColumn > 0) || (aRange.EndRow > 0) ) + extendUsedArea( aRange ); } void OoxWorksheetFragment::importSheetFormatPr( const AttributeList& rAttribs ) @@ -619,7 +624,12 @@ void OoxWorksheetFragment::importDimension( RecordInputStream& rStrm ) aBinRange.read( rStrm ); CellRangeAddress aRange; getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() ); - setDimension( aRange ); + /* BIFF12 stores the used area, if existing, or "A1" if the sheet is + empty. In case of "A1", the dimension at the WorksheetHelper object + will not be set. If the cell A1 exists, the used area will be updated + while importing the cell. */ + if( (aRange.EndColumn > 0) || (aRange.EndRow > 0) ) + extendUsedArea( aRange ); } void OoxWorksheetFragment::importSheetFormatPr( RecordInputStream& rStrm ) @@ -1056,15 +1066,21 @@ void BiffWorksheetFragment::importDataValidation() void BiffWorksheetFragment::importDimension() { + // 32-bit row indexes in BIFF8 + bool bInt32Rows = (mrStrm.getRecId() == BIFF3_ID_DIMENSION) && (getBiff() == BIFF8); BinRange aBinRange; - aBinRange.read( mrStrm, true, (mrStrm.getRecId() == BIFF3_ID_DIMENSION) && (getBiff() == BIFF8) ); - // first unused row/column index in BIFF, not last used - if( aBinRange.maFirst.mnCol < aBinRange.maLast.mnCol ) --aBinRange.maLast.mnCol; - if( aBinRange.maFirst.mnRow < aBinRange.maLast.mnRow ) --aBinRange.maLast.mnRow; - // set dimension - CellRangeAddress aRange; - getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() ); - setDimension( aRange ); + aBinRange.read( mrStrm, true, bInt32Rows ); + /* BIFF stores the used area with end column and end row increased by 1 + (first unused column and row). */ + if( (aBinRange.maFirst.mnCol < aBinRange.maLast.mnCol) && (aBinRange.maFirst.mnRow < aBinRange.maLast.mnRow) ) + { + // reduce range to used area + --aBinRange.maLast.mnCol; + --aBinRange.maLast.mnRow; + CellRangeAddress aRange; + getAddressConverter().convertToCellRangeUnchecked( aRange, aBinRange, getSheetIndex() ); + extendUsedArea( aRange ); + } } void BiffWorksheetFragment::importHyperlink() diff --git a/oox/source/xls/worksheethelper.cxx b/oox/source/xls/worksheethelper.cxx index 381def644ce5..99c2d844f4b5 100644 --- a/oox/source/xls/worksheethelper.cxx +++ b/oox/source/xls/worksheethelper.cxx @@ -76,6 +76,7 @@ using ::rtl::OUString; using ::rtl::OUStringBuffer; using ::com::sun::star::awt::Point; +using ::com::sun::star::awt::Rectangle; using ::com::sun::star::awt::Size; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::drawing::XDrawPage; @@ -124,11 +125,11 @@ namespace xls { namespace { -void lclUpdateProgressBar( ISegmentProgressBarRef xProgressBar, const CellRangeAddress& rDimension, sal_Int32 nRow ) +void lclUpdateProgressBar( ISegmentProgressBarRef xProgressBar, const CellRangeAddress& rUsedArea, sal_Int32 nRow ) { - if( xProgressBar.get() && (rDimension.StartRow <= nRow) && (nRow <= rDimension.EndRow) ) + if( xProgressBar.get() && (rUsedArea.StartRow <= nRow) && (nRow <= rUsedArea.EndRow) ) { - double fPosition = static_cast< double >( nRow - rDimension.StartRow + 1 ) / (rDimension.EndRow - rDimension.StartRow + 1); + double fPosition = static_cast< double >( nRow - rUsedArea.StartRow + 1 ) / (rUsedArea.EndRow - rUsedArea.StartRow + 1); if( xProgressBar->getPosition() < fPosition ) xProgressBar->setPosition( fPosition ); } @@ -370,7 +371,7 @@ public: /** Returns the type of this sheet. */ inline WorksheetType getSheetType() const { return meSheetType; } /** Returns the index of the current sheet. */ - inline sal_Int16 getSheetIndex() const { return mnSheet; } + inline sal_Int16 getSheetIndex() const { return maUsedArea.Sheet; } /** Returns the XSpreadsheet interface of the current sheet. */ inline const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheet >& getSheet() const { return mxSheet; } @@ -394,13 +395,18 @@ public: /** Returns the XDrawPage interface of the draw page of the current sheet. */ Reference< XDrawPage > getDrawPage() const; + /** Returns the size of the entire drawing page in 1/100 mm. */ + Size getDrawPageSize() const; - /** Returns the absolute cell position in 1/100 mm. */ + /** Returns the absolute position of the top-left corner of the cell in 1/100 mm. */ Point getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const; - /** Returns the cell size in 1/100 mm. */ + /** Returns the size of the cell in 1/100 mm. */ Size getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const; - /** Returns the size of the entire drawing page in 1/100 mm. */ - Size getDrawPageSize() const; + + /** Returns the address of the cell that contains the passed point in 1/100 mm. */ + CellAddress getCellAddressFromPosition( const Point& rPosition, const CellAddress* pStartAddr = 0 ) const; + /** Returns the cell range address that contains the passed rectangle in 1/100 mm. */ + CellRangeAddress getCellRangeFromRectangle( const Rectangle& rRect ) const; /** Returns the worksheet settings object. */ inline WorksheetSettings& getWorksheetSettings() { return maSheetSett; } @@ -419,8 +425,6 @@ public: /** Changes the current sheet type. */ inline void setSheetType( WorksheetType eSheetType ) { meSheetType = eSheetType; } - /** Sets the dimension (used area) of the sheet. */ - void setDimension( const CellRangeAddress& rRange ); /** Stores the cell format at the passed address. */ void setCellFormat( const CellModel& rModel ); /** Merges the cells in the passed cell range. */ @@ -436,6 +440,13 @@ public: /** Sets the path to the legacy VML drawing fragment of this sheet. */ void setVmlDrawingPath( const OUString& rVmlDrawingPath ); + /** Extends the used area of this sheet by the passed cell position. */ + void extendUsedArea( const CellAddress& rAddress ); + /** Extends the used area of this sheet by the passed cell range. */ + void extendUsedArea( const CellRangeAddress& rRange ); + /** Extends the shape bounding box by the position and size of the passed rectangle. */ + void extendShapeBoundingBox( const Rectangle& rShapeRect ); + /** Sets base width for all columns (without padding pixels). This value is only used, if base width has not been set with setDefaultColumnWidth(). */ void setBaseColumnWidth( sal_Int32 nWidth ); @@ -536,6 +547,8 @@ private: void finalizeDrawing(); /** Imports the drawing layer of the sheet (VML part). */ void finalizeVmlDrawing(); + /** Extends the used cell area with the area used by drawing objects. */ + void finalizeUsedArea(); /** Converts column properties for all columns in the sheet. */ void convertColumns(); @@ -560,7 +573,7 @@ private: const OUString maSheetCellRanges; /// Service name for a SheetCellRanges object. const OUString maUrlTextField; /// Service name for a URL text field. const CellAddress& mrMaxApiPos; /// Reference to maximum Calc cell address from address converter. - CellRangeAddress maDimension; /// Dimension (used) area of the sheet. + CellRangeAddress maUsedArea; /// Used area of the sheet, and sheet index of the sheet. ColumnModel maDefColModel; /// Default column formatting. ColumnModelMap maColModels; /// Columns sorted by first column index. RowModel maDefRowModel; /// Default row formatting. @@ -581,12 +594,12 @@ private: VmlDrawingPtr mxVmlDrawing; /// Collection of all VML shapes. OUString maDrawingPath; /// Path to DrawingML fragment. OUString maVmlDrawingPath; /// Path to legacy VML drawing fragment. + Rectangle maShapeBoundingBox; /// Bounding box for all shapes from all drawings. ISegmentProgressBarRef mxProgressBar; /// Sheet progress bar. ISegmentProgressBarRef mxRowProgress; /// Progress bar for row/cell processing. ISegmentProgressBarRef mxFinalProgress; /// Progress bar for finalization. WorksheetType meSheetType; /// Type of this sheet. Reference< XSpreadsheet > mxSheet; /// Reference to the current sheet. - sal_Int16 mnSheet; /// Index of the current sheet. bool mbHasDefWidth; /// True = default column width is set from defaultColWidth attribute. }; @@ -599,6 +612,7 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBar maSheetCellRanges( CREATE_OUSTRING( "com.sun.star.sheet.SheetCellRanges" ) ), maUrlTextField( CREATE_OUSTRING( "com.sun.star.text.TextField.URL" ) ), mrMaxApiPos( rHelper.getAddressConverter().getMaxApiAddress() ), + maUsedArea( nSheet, SAL_MAX_INT32, SAL_MAX_INT32, -1, -1 ), maSheetSett( *this ), maSharedFmlas( *this ), maCondFormats( *this ), @@ -607,14 +621,11 @@ WorksheetData::WorksheetData( const WorkbookHelper& rHelper, ISegmentProgressBar maSheetViewSett( *this ), mxProgressBar( xProgressBar ), meSheetType( eSheetType ), - mnSheet( nSheet ), mbHasDefWidth( false ) { mxSheet = getSheetFromDoc( nSheet ); if( !mxSheet.is() ) - mnSheet = -1; - - maDimension.Sheet = mnSheet; + maUsedArea.Sheet = -1; // default column settings (width and hidden state may be updated later) maDefColModel.mfWidth = 8.5; @@ -727,7 +738,7 @@ Reference< XTableColumns > WorksheetData::getColumns( sal_Int32 nFirstCol, sal_I nLastCol = ::std::min( nLastCol, mrMaxApiPos.Column ); if( (0 <= nFirstCol) && (nFirstCol <= nLastCol) ) { - Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( mnSheet, nFirstCol, 0, nLastCol, 0 ) ), UNO_QUERY ); + Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), nFirstCol, 0, nLastCol, 0 ) ), UNO_QUERY ); if( xRange.is() ) xColumns = xRange->getColumns(); } @@ -740,7 +751,7 @@ Reference< XTableRows > WorksheetData::getRows( sal_Int32 nFirstRow, sal_Int32 n nLastRow = ::std::min( nLastRow, mrMaxApiPos.Row ); if( (0 <= nFirstRow) && (nFirstRow <= nLastRow) ) { - Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( mnSheet, 0, nFirstRow, 0, nLastRow ) ), UNO_QUERY ); + Reference< XColumnRowRange > xRange( getCellRange( CellRangeAddress( getSheetIndex(), 0, nFirstRow, 0, nLastRow ) ), UNO_QUERY ); if( xRange.is() ) xRows = xRange->getRows(); } @@ -752,8 +763,7 @@ Reference< XDrawPage > WorksheetData::getDrawPage() const Reference< XDrawPage > xDrawPage; try { - Reference< XDrawPageSupplier > xDrawPageSupp( mxSheet, UNO_QUERY_THROW ); - xDrawPage = xDrawPageSupp->getDrawPage(); + xDrawPage = Reference< XDrawPageSupplier >( mxSheet, UNO_QUERY_THROW )->getDrawPage(); } catch( Exception& ) { @@ -761,10 +771,18 @@ Reference< XDrawPage > WorksheetData::getDrawPage() const return xDrawPage; } +Size WorksheetData::getDrawPageSize() const +{ + Size aSize; + PropertySet aRangeProp( getCellRange( CellRangeAddress( getSheetIndex(), 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); + aRangeProp.getProperty( aSize, PROP_Size ); + return aSize; +} + Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const { Point aPoint; - PropertySet aCellProp( getCell( CellAddress( mnSheet, nCol, nRow ) ) ); + PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) ); aCellProp.getProperty( aPoint, PROP_Position ); return aPoint; } @@ -772,22 +790,59 @@ Point WorksheetData::getCellPosition( sal_Int32 nCol, sal_Int32 nRow ) const Size WorksheetData::getCellSize( sal_Int32 nCol, sal_Int32 nRow ) const { Size aSize; - PropertySet aCellProp( getCell( CellAddress( mnSheet, nCol, nRow ) ) ); + PropertySet aCellProp( getCell( CellAddress( getSheetIndex(), nCol, nRow ) ) ); aCellProp.getProperty( aSize, PROP_Size ); return aSize; } -Size WorksheetData::getDrawPageSize() const +CellAddress WorksheetData::getCellAddressFromPosition( const Point& rPosition, const CellAddress* pStartAddr ) const { - Size aSize; - PropertySet aRangeProp( getCellRange( CellRangeAddress( mnSheet, 0, 0, mrMaxApiPos.Column, mrMaxApiPos.Row ) ) ); - aRangeProp.getProperty( aSize, PROP_Size ); - return aSize; + // prepare start address for search loop + sal_Int32 nCol = pStartAddr ? ::std::min< sal_Int32 >( pStartAddr->Column + 1, mrMaxApiPos.Column ) : 1; + sal_Int32 nRow = pStartAddr ? ::std::min< sal_Int32 >( pStartAddr->Row + 1, mrMaxApiPos.Row ) : 1; + + /* The loop will find the column/row index of the cell right of/below + the cell containing the passed point, unless the point is located at + the top or left border of the containing cell. */ + bool bNextCol = true; + bool bNextRow = true; + Point aCellPos; + do + { + aCellPos = getCellPosition( nCol, nRow ); + if( bNextCol && ((bNextCol = (aCellPos.X < rPosition.X) && (nCol < mrMaxApiPos.Column)) == true) ) + ++nCol; + if( bNextRow && ((bNextRow = (aCellPos.Y < rPosition.Y) && (nRow < mrMaxApiPos.Row)) == true) ) + ++nRow; + } + while( bNextCol || bNextRow ); + + /* The cell left of/above the current search position contains the passed + point, unless the point is located on the top/left border of the cell, + or the last column/row of the sheet has been reached. */ + if( aCellPos.X > rPosition.X ) --nCol; + if( aCellPos.Y > rPosition.Y ) --nRow; + return CellAddress( getSheetIndex(), nCol, nRow ); } -void WorksheetData::setDimension( const CellRangeAddress& rRange ) +CellRangeAddress WorksheetData::getCellRangeFromRectangle( const Rectangle& rRect ) const { - maDimension = rRange; + CellAddress aStartAddr = getCellAddressFromPosition( Point( rRect.X, rRect.Y ) ); + Point aBotRight( rRect.X + rRect.Width, rRect.Y + rRect.Height ); + CellAddress aEndAddr = getCellAddressFromPosition( aBotRight ); + bool bMultiCols = aStartAddr.Column < aEndAddr.Column; + bool bMultiRows = aStartAddr.Row < aEndAddr.Row; + if( bMultiCols || bMultiRows ) + { + /* Reduce end position of the cell range to previous column or row, if + the rectangle ends exactly between two columns or rows. */ + Point aEndPos = getCellPosition( aEndAddr.Column, aEndAddr.Row ); + if( bMultiCols && (aBotRight.X <= aEndPos.X) ) + --aEndAddr.Column; + if( bMultiRows && (aBotRight.Y <= aEndPos.Y) ) + --aEndAddr.Row; + } + return CellRangeAddress( getSheetIndex(), aStartAddr.Column, aStartAddr.Row, aEndAddr.Column, aEndAddr.Row ); } void WorksheetData::setCellFormat( const CellModel& rModel ) @@ -874,6 +929,38 @@ void WorksheetData::setVmlDrawingPath( const OUString& rVmlDrawingPath ) maVmlDrawingPath = rVmlDrawingPath; } +void WorksheetData::extendUsedArea( const CellAddress& rAddress ) +{ + maUsedArea.StartColumn = ::std::min( maUsedArea.StartColumn, rAddress.Column ); + maUsedArea.StartRow = ::std::min( maUsedArea.StartRow, rAddress.Row ); + maUsedArea.EndColumn = ::std::max( maUsedArea.EndColumn, rAddress.Column ); + maUsedArea.EndRow = ::std::max( maUsedArea.EndRow, rAddress.Row ); +} + +void WorksheetData::extendUsedArea( const CellRangeAddress& rRange ) +{ + extendUsedArea( CellAddress( rRange.Sheet, rRange.StartColumn, rRange.StartRow ) ); + extendUsedArea( CellAddress( rRange.Sheet, rRange.EndColumn, rRange.EndRow ) ); +} + +void WorksheetData::extendShapeBoundingBox( const Rectangle& rShapeRect ) +{ + if( (maShapeBoundingBox.Width == 0) && (maShapeBoundingBox.Height == 0) ) + { + // width and height of maShapeBoundingBox are assumed to be zero on first cell + maShapeBoundingBox = rShapeRect; + } + else + { + sal_Int32 nEndX = ::std::max( maShapeBoundingBox.X + maShapeBoundingBox.Width, rShapeRect.X + rShapeRect.Width ); + sal_Int32 nEndY = ::std::max( maShapeBoundingBox.Y + maShapeBoundingBox.Height, rShapeRect.Y + rShapeRect.Height ); + maShapeBoundingBox.X = ::std::min( maShapeBoundingBox.X, rShapeRect.X ); + maShapeBoundingBox.Y = ::std::min( maShapeBoundingBox.Y, rShapeRect.Y ); + maShapeBoundingBox.Width = nEndX - maShapeBoundingBox.X; + maShapeBoundingBox.Height = nEndY - maShapeBoundingBox.Y; + } +} + void WorksheetData::setBaseColumnWidth( sal_Int32 nWidth ) { // do not modify width, if setDefaultColumnWidth() has been used @@ -948,12 +1035,12 @@ void WorksheetData::setRowModel( const RowModel& rModel ) if( maRowModels.empty() || !maRowModels.rbegin()->second.tryExpand( rModel ) ) maRowModels[ nFirstRow ] = rModel; } - lclUpdateProgressBar( mxRowProgress, maDimension, nLastRow ); + lclUpdateProgressBar( mxRowProgress, maUsedArea, nLastRow ); } void WorksheetData::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol, sal_Int32 nXfId ) const { - CellRangeAddress aRange( mnSheet, nFirstCol, 0, nLastCol, mrMaxApiPos.Row ); + CellRangeAddress aRange( getSheetIndex(), nFirstCol, 0, nLastCol, mrMaxApiPos.Row ); if( getAddressConverter().validateCellRange( aRange, true, false ) ) { PropertySet aPropSet( getCellRange( aRange ) ); @@ -963,7 +1050,7 @@ void WorksheetData::convertColumnFormat( sal_Int32 nFirstCol, sal_Int32 nLastCol void WorksheetData::convertRowFormat( sal_Int32 nFirstRow, sal_Int32 nLastRow, sal_Int32 nXfId ) const { - CellRangeAddress aRange( mnSheet, 0, nFirstRow, mrMaxApiPos.Column, nLastRow ); + CellRangeAddress aRange( getSheetIndex(), 0, nFirstRow, mrMaxApiPos.Column, nLastRow ); if( getAddressConverter().validateCellRange( aRange, true, false ) ) { PropertySet aPropSet( getCellRange( aRange ) ); @@ -979,7 +1066,7 @@ void WorksheetData::initializeWorksheetImport() /* Remember current sheet index in global data, needed by some global objects, e.g. the chart converter. */ - setCurrentSheetIndex( mnSheet ); + setCurrentSheetIndex( getSheetIndex() ); } void WorksheetData::finalizeWorksheetImport() @@ -994,6 +1081,8 @@ void WorksheetData::finalizeWorksheetImport() maCondFormats.finalizeImport(); maPageSett.finalizeImport(); maSheetViewSett.finalizeImport(); + maSheetSett.finalizeImport(); + lclUpdateProgressBar( mxFinalProgress, 0.5 ); convertColumns(); convertRows(); @@ -1001,6 +1090,7 @@ void WorksheetData::finalizeWorksheetImport() finalizeDrawing(); finalizeVmlDrawing(); maComments.finalizeImport(); // after VML drawing + finalizeUsedArea(); // after DML and VML drawing lclUpdateProgressBar( mxFinalProgress, 1.0 ); // reset current sheet index in global data @@ -1162,7 +1252,7 @@ void WorksheetData::finalizeHyperlinkRanges() const OUString aUrl = getHyperlinkUrl( *aIt ); // try to insert URL into each cell of the range if( aUrl.getLength() > 0 ) - for( CellAddress aAddress( mnSheet, aIt->maRange.StartColumn, aIt->maRange.StartRow ); aAddress.Row <= aIt->maRange.EndRow; ++aAddress.Row ) + for( CellAddress aAddress( getSheetIndex(), aIt->maRange.StartColumn, aIt->maRange.StartRow ); aAddress.Row <= aIt->maRange.EndRow; ++aAddress.Row ) for( aAddress.Column = aIt->maRange.StartColumn; aAddress.Column <= aIt->maRange.EndColumn; ++aAddress.Column ) insertHyperlink( aAddress, aUrl ); } @@ -1348,13 +1438,13 @@ void WorksheetData::finalizeMergedRange( const CellRangeAddress& rRange ) xMerge->merge( sal_True ); // if merging this range worked (no overlapping merged ranges), update cell borders - Reference< XCell > xTopLeft( getCell( CellAddress( mnSheet, rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW ); + Reference< XCell > xTopLeft( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.StartRow ) ), UNO_SET_THROW ); PropertySet aTopLeftProp( xTopLeft ); // copy right border of top-right cell to right border of top-left cell if( bMultiCol ) { - PropertySet aTopRightProp( getCell( CellAddress( mnSheet, rRange.EndColumn, rRange.StartRow ) ) ); + PropertySet aTopRightProp( getCell( CellAddress( getSheetIndex(), rRange.EndColumn, rRange.StartRow ) ) ); BorderLine aLine; if( aTopRightProp.getProperty( aLine, PROP_RightBorder ) ) aTopLeftProp.setProperty( PROP_RightBorder, aLine ); @@ -1363,7 +1453,7 @@ void WorksheetData::finalizeMergedRange( const CellRangeAddress& rRange ) // copy bottom border of bottom-left cell to bottom border of top-left cell if( bMultiRow ) { - PropertySet aBottomLeftProp( getCell( CellAddress( mnSheet, rRange.StartColumn, rRange.EndRow ) ) ); + PropertySet aBottomLeftProp( getCell( CellAddress( getSheetIndex(), rRange.StartColumn, rRange.EndRow ) ) ); BorderLine aLine; if( aBottomLeftProp.getProperty( aLine, PROP_BottomBorder ) ) aTopLeftProp.setProperty( PROP_BottomBorder, aLine ); @@ -1403,6 +1493,26 @@ void WorksheetData::finalizeVmlDrawing() importOoxFragment( new OoxVmlDrawingFragment( *this, maVmlDrawingPath ) ); } +void WorksheetData::finalizeUsedArea() +{ + /* Extend used area of the sheet by cells covered with drawing objects. + Needed if the imported document is inserted as "OLE object from file" + and thus does not provide an OLE size property by itself. */ + if( (maShapeBoundingBox.Width > 0) || (maShapeBoundingBox.Height > 0) ) + extendUsedArea( getCellRangeFromRectangle( maShapeBoundingBox ) ); + + // if no used area is set, default to A1 + if( maUsedArea.StartColumn > maUsedArea.EndColumn ) + maUsedArea.StartColumn = maUsedArea.EndColumn = 0; + if( maUsedArea.StartRow > maUsedArea.EndRow ) + maUsedArea.StartRow = maUsedArea.EndRow = 0; + + /* Register the used area of this sheet in global view settings. The + global view settings will set the visible area if this document is an + embedded OLE object. */ + getViewSettings().setSheetUsedArea( maUsedArea ); +} + void WorksheetData::convertColumns() { sal_Int32 nNextCol = 0; @@ -1549,14 +1659,14 @@ void WorksheetData::groupColumnsOrRows( sal_Int32 nFirstColRow, sal_Int32 nLastC Reference< XSheetOutline > xOutline( mxSheet, UNO_QUERY_THROW ); if( bRows ) { - CellRangeAddress aRange( mnSheet, 0, nFirstColRow, 0, nLastColRow ); + CellRangeAddress aRange( getSheetIndex(), 0, nFirstColRow, 0, nLastColRow ); xOutline->group( aRange, ::com::sun::star::table::TableOrientation_ROWS ); if( bCollapse ) xOutline->hideDetail( aRange ); } else { - CellRangeAddress aRange( mnSheet, nFirstColRow, 0, nLastColRow, 0 ); + CellRangeAddress aRange( getSheetIndex(), nFirstColRow, 0, nLastColRow, 0 ); xOutline->group( aRange, ::com::sun::star::table::TableOrientation_COLUMNS ); if( bCollapse ) xOutline->hideDetail( aRange ); @@ -1856,11 +1966,6 @@ void WorksheetHelper::setSheetType( WorksheetType eSheetType ) mrSheetData.setSheetType( eSheetType ); } -void WorksheetHelper::setDimension( const CellRangeAddress& rRange ) -{ - mrSheetData.setDimension( rRange ); -} - void WorksheetHelper::setCellFormat( const CellModel& rModel ) { mrSheetData.setCellFormat( rModel ); @@ -2003,6 +2108,21 @@ void WorksheetHelper::setVmlDrawingPath( const OUString& rVmlDrawingPath ) mrSheetData.setVmlDrawingPath( rVmlDrawingPath ); } +void WorksheetHelper::extendUsedArea( const CellAddress& rAddress ) +{ + mrSheetData.extendUsedArea( rAddress ); +} + +void WorksheetHelper::extendUsedArea( const CellRangeAddress& rRange ) +{ + mrSheetData.extendUsedArea( rRange ); +} + +void WorksheetHelper::extendShapeBoundingBox( const Rectangle& rShapeRect ) +{ + mrSheetData.extendShapeBoundingBox( rShapeRect ); +} + void WorksheetHelper::setBaseColumnWidth( sal_Int32 nWidth ) { mrSheetData.setBaseColumnWidth( nWidth ); diff --git a/oox/source/xls/worksheetsettings.cxx b/oox/source/xls/worksheetsettings.cxx index 6a42c38e1647..0cc9d5f17780 100644 --- a/oox/source/xls/worksheetsettings.cxx +++ b/oox/source/xls/worksheetsettings.cxx @@ -26,15 +26,19 @@ ************************************************************************/ #include "oox/xls/worksheetsettings.hxx" -#include <com/sun/star/util/XProtectable.hpp> -#include "properties.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/recordinputstream.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/pagesettings.hxx" #include "oox/xls/workbooksettings.hxx" +#include "oox/core/filterbase.hxx" +#include "properties.hxx" + +#include <com/sun/star/util/XProtectable.hpp> using ::rtl::OUString; +using ::com::sun::star::beans::XPropertySet; +using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Exception; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::UNO_QUERY_THROW; @@ -319,6 +323,12 @@ void WorksheetSettings::finalizeImport() // VBA code name PropertySet aPropSet( getSheet() ); aPropSet.setProperty( PROP_CodeName, maSheetSettings.maCodeName ); + + if (!maSheetSettings.maTabColor.isAuto()) + { + sal_Int32 nColor = maSheetSettings.maTabColor.getColor(getBaseFilter().getGraphicHelper()); + aPropSet.setProperty(PROP_TabColor, nColor); + } } // ============================================================================ |