From 8dfb14e710975ba9e5fbab2a83aa1a516ba3f1d2 Mon Sep 17 00:00:00 2001 From: Daniel Rentz Date: Fri, 15 Jan 2010 12:00:39 +0100 Subject: dr74: migrate changes to hg --- oox/inc/oox/drawingml/textbodyproperties.hxx | 4 + oox/inc/oox/xls/drawingfragment.hxx | 2 +- oox/inc/oox/xls/stylesbuffer.hxx | 33 +++- oox/source/core/xmlfilterbase.cxx | 87 +++++++---- oox/source/drawingml/makefile.mk | 1 + oox/source/drawingml/shape.cxx | 2 +- oox/source/export/drawingml.cxx | 11 +- oox/source/ole/axcontrol.cxx | 25 ++- oox/source/xls/biffhelper.cxx | 58 ++++--- oox/source/xls/formulabase.cxx | 123 ++++++++------- oox/source/xls/stylesbuffer.cxx | 224 ++++++++++++++++++++------- oox/source/xls/viewsettings.cxx | 2 +- 12 files changed, 396 insertions(+), 176 deletions(-) (limited to 'oox') diff --git a/oox/inc/oox/drawingml/textbodyproperties.hxx b/oox/inc/oox/drawingml/textbodyproperties.hxx index f0824843b420..deb8b6bd1c62 100644 --- a/oox/inc/oox/drawingml/textbodyproperties.hxx +++ b/oox/inc/oox/drawingml/textbodyproperties.hxx @@ -44,6 +44,10 @@ struct TextBodyProperties PropertyMap maPropertyMap; OptValue< sal_Int32 > moRotation; OptValue< sal_Int32 > moVert; + + explicit TextBodyProperties(); + + void pushToPropMap( PropertyMap& rPropMap ) const; }; // ============================================================================ diff --git a/oox/inc/oox/xls/drawingfragment.hxx b/oox/inc/oox/xls/drawingfragment.hxx index 67009f436360..05e43b33b427 100644 --- a/oox/inc/oox/xls/drawingfragment.hxx +++ b/oox/inc/oox/xls/drawingfragment.hxx @@ -184,7 +184,7 @@ public: /** Converts additional form control properties from the passed VML shape client data. */ virtual void convertControlClientData( - const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel, + const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel, const ::oox::vml::ShapeClientData& rClientData ) const; }; diff --git a/oox/inc/oox/xls/stylesbuffer.hxx b/oox/inc/oox/xls/stylesbuffer.hxx index c79ef46e5859..d780539e1656 100644 --- a/oox/inc/oox/xls/stylesbuffer.hxx +++ b/oox/inc/oox/xls/stylesbuffer.hxx @@ -512,8 +512,13 @@ struct ApiBorderData bool mbDiagUsed; /// True = diagonal line format used. explicit ApiBorderData(); + + /** Returns true, if any of the outer border lines is visible. */ + bool hasAnyOuterBorder() const; }; +bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight ); + // ============================================================================ class Border : public WorkbookHelper @@ -547,6 +552,11 @@ public: /** Final processing after import of all style settings. */ void finalizeImport(); + /** Returns the border model structure. */ + inline const BorderModel& getModel() const { return maModel; } + /** Returns the converted API border data struct. */ + inline const ApiBorderData& getApiData() const { return maApiData; } + /** Writes all border attributes to the passed property map. */ void writeToPropertyMap( PropertyMap& rPropMap ) const; @@ -622,6 +632,8 @@ struct ApiSolidFillData explicit ApiSolidFillData(); }; +bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight ); + // ============================================================================ /** Contains cell fill attributes, either a pattern fill or a gradient fill. */ @@ -668,6 +680,13 @@ public: /** Final processing after import of all style settings. */ void finalizeImport(); + /** Returns the fill pattern model structure, if extant. */ + inline const PatternFillModel* getPatternModel() const { return mxPatternModel.get(); } + /** Returns the fill gradient model structure, if extant. */ + inline const GradientFillModel* getGradientModel() const { return mxGradientModel.get(); } + /** Returns the converted API fill data struct. */ + inline const ApiSolidFillData& getApiData() const { return maApiData; } + /** Writes all fill attributes to the passed property map. */ void writeToPropertyMap( PropertyMap& rPropMap ) const; @@ -737,6 +756,9 @@ public: /** Final processing after import of all style settings. */ void finalizeImport(); + /** Returns true, if the XF is a cell XF, and false, if it is a style XF. */ + inline bool isCellXf() const { return maModel.mbCellXf; } + /** Returns the referred font object. */ FontRef getFont() const; /** Returns the alignment data of this style. */ @@ -754,13 +776,13 @@ public: private: /** Sets 'attribute used' flags from the passed BIFF bit field. */ void setBiffUsedFlags( sal_uInt8 nUsedFlags ); - /** Updates own used flags from the passed cell style XF. */ - void updateUsedFlags( const Xf& rStyleXf ); private: XfModel maModel; /// Cell XF or style XF model data. Alignment maAlignment; /// Cell alignment data. Protection maProtection; /// Cell protection data. + ::com::sun::star::table::CellVertJustify + meRotationRef; /// Rotation reference dependent on border. }; typedef ::boost::shared_ptr< Xf > XfRef; @@ -967,6 +989,8 @@ public: sal_Int32 getPaletteColor( sal_Int32 nIndex ) const; /** Returns the specified font object. */ FontRef getFont( sal_Int32 nFontId ) const; + /** Returns the specified border object. */ + BorderRef getBorder( sal_Int32 nBorderId ) const; /** Returns the specified cell format object. */ XfRef getCellXf( sal_Int32 nXfId ) const; /** Returns the specified style format object. */ @@ -981,6 +1005,11 @@ public: /** Returns the model of the default application font (used in the "Normal" cell style). */ const FontModel& getDefaultFontModel() const; + /** Returns true, if the specified borders are equal. */ + bool equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const; + /** Returns true, if the specified fills are equal. */ + bool equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const; + /** Returns the default style sheet for unused cells. */ ::rtl::OUString getDefaultStyleName() const; /** Creates the style sheet described by the style XF with the passed identifier. */ diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index 07652c5c447b..2205ce57366f 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -88,13 +88,25 @@ namespace core { // ============================================================================ +namespace { + +bool lclHasSuffix( const OUString& rFragmentPath, const OUString& rSuffix ) +{ + sal_Int32 nSuffixPos = rFragmentPath.getLength() - rSuffix.getLength(); + return (nSuffixPos >= 0) && rFragmentPath.match( rSuffix, nSuffixPos ); +} + +} // namespace + +// ============================================================================ + struct XmlFilterBaseImpl { typedef RefMap< OUString, Relations > RelationsMap; + Reference< XFastParser > mxFastParser; OUString maBinSuffix; - Reference< XFastTokenHandler > - mxTokenHandler; + OUString maVmlSuffix; RelationsMap maRelationsMap; TextFieldStack maTextFieldStack; explicit XmlFilterBaseImpl(); @@ -104,7 +116,7 @@ struct XmlFilterBaseImpl XmlFilterBaseImpl::XmlFilterBaseImpl() : maBinSuffix( CREATE_OUSTRING( ".bin" ) ), - mxTokenHandler( new FastTokenHandler ) + maVmlSuffix( CREATE_OUSTRING( ".vml" ) ) { } @@ -116,6 +128,37 @@ XmlFilterBase::XmlFilterBase( const Reference< XMultiServiceFactory >& rxGlobalF mnRelId( 1 ), mnMaxDocId( 0 ) { + try + { + // create the fast parser + mxImpl->mxFastParser.set( rxGlobalFactory->createInstance( CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW ); + mxImpl->mxFastParser->setTokenHandler( new FastTokenHandler ); + + // register XML namespaces + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://www.w3.org/XML/1998/namespace" ), NMSP_XML ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS ); + + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/main" ), NMSP_DRAWINGML ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ), NMSP_DIAGRAM ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/chart" ), NMSP_CHART ); + + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:vml" ), NMSP_VML ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:office" ), NMSP_OFFICE ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:word" ), NMSP_VML_DOC ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:excel" ), NMSP_VML_XLS ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:powerpoint" ), NMSP_VML_PPT ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.microsoft.com/office/2006/activeX" ), NMSP_AX ); + + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/spreadsheetml/2006/main"), NMSP_XLS ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" ), NMSP_XDR ); + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.microsoft.com/office/excel/2006/main" ), NMSP_XM ); + + mxImpl->mxFastParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/presentationml/2006/main"), NMSP_PPT ); + } + catch( Exception& ) + { + } } XmlFilterBase::~XmlFilterBase() @@ -143,8 +186,7 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r return false; // try to import binary streams (fragment extension must be '.bin') - sal_Int32 nBinSuffixPos = aFragmentPath.getLength() - mxImpl->maBinSuffix.getLength(); - if( (nBinSuffixPos >= 0) && aFragmentPath.match( mxImpl->maBinSuffix, nBinSuffixPos ) ) + if( lclHasSuffix( aFragmentPath, mxImpl->maBinSuffix ) ) { try { @@ -173,40 +215,16 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r if( !xDocHandler.is() ) return false; + // check that the fast parser exists + if( !mxImpl->mxFastParser.is() ) + return false; + // try to import XML stream try { // try to open the fragment stream (this may fail - do not assert) Reference< XInputStream > xInStrm( rxHandler->openFragmentStream(), UNO_SET_THROW ); - // create the fast parser - Reference< XFastParser > xParser( getGlobalFactory()->createInstance( - CREATE_OUSTRING( "com.sun.star.xml.sax.FastParser" ) ), UNO_QUERY_THROW ); - xParser->setFastDocumentHandler( xDocHandler ); - xParser->setTokenHandler( mxImpl->mxTokenHandler ); - - // register XML namespaces - xParser->registerNamespace( CREATE_OUSTRING( "http://www.w3.org/XML/1998/namespace" ), NMSP_XML ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/package/2006/relationships" ), NMSP_PACKAGE_RELATIONSHIPS ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/officeDocument/2006/relationships" ), NMSP_RELATIONSHIPS ); - - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/main" ), NMSP_DRAWINGML ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/diagram" ), NMSP_DIAGRAM ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/chart" ), NMSP_CHART ); - - xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:vml" ), NMSP_VML ); - xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:office" ), NMSP_OFFICE ); - xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:word" ), NMSP_VML_DOC ); - xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:excel" ), NMSP_VML_XLS ); - xParser->registerNamespace( CREATE_OUSTRING( "urn:schemas-microsoft-com:office:powerpoint" ), NMSP_VML_PPT ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.microsoft.com/office/2006/activeX" ), NMSP_AX ); - - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/spreadsheetml/2006/main"), NMSP_XLS ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" ), NMSP_XDR ); - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.microsoft.com/office/excel/2006/main" ), NMSP_XM ); - - xParser->registerNamespace( CREATE_OUSTRING( "http://schemas.openxmlformats.org/presentationml/2006/main"), NMSP_PPT ); - // create the input source and parse the stream InputSource aSource; aSource.aInputStream = xInStrm; @@ -214,7 +232,8 @@ bool XmlFilterBase::importFragment( const ::rtl::Reference< FragmentHandler >& r // own try/catch block for showing parser failure assertion with fragment path try { - xParser->parseStream( aSource ); + mxImpl->mxFastParser->setFastDocumentHandler( xDocHandler ); + mxImpl->mxFastParser->parseStream( aSource ); return true; } catch( Exception& ) diff --git a/oox/source/drawingml/makefile.mk b/oox/source/drawingml/makefile.mk index 329d748288b1..52fc3760ecae 100644 --- a/oox/source/drawingml/makefile.mk +++ b/oox/source/drawingml/makefile.mk @@ -70,6 +70,7 @@ SLOFILES = \ $(SLO)$/spdefcontext.obj\ $(SLO)$/textbody.obj\ $(SLO)$/textbodycontext.obj\ + $(SLO)$/textbodyproperties.obj\ $(SLO)$/textbodypropertiescontext.obj\ $(SLO)$/textcharacterproperties.obj\ $(SLO)$/textcharacterpropertiescontext.obj\ diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index b1d68fabcb11..986477ddc449 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -418,7 +418,7 @@ Reference< XShape > Shape::createAndInsert( // add properties from textbody to shape properties if( mpTextBody.get() ) - aShapeProperties.insert( mpTextBody->getTextProperties().maPropertyMap.begin(), mpTextBody->getTextProperties().maPropertyMap.end() ); + mpTextBody->getTextProperties().pushToPropMap( aShapeProperties ); // applying properties PropertySet aPropSet( xSet ); diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index f681477076bf..2880e61e4fc6 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -1342,15 +1342,10 @@ void DrawingML::WriteConnectorConnections( EscherConnectorListEntry& rConnectorE // from sw/source/filter/ww8/wrtw8num.cxx for default bullets to export to MS intact static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, String& rFontName) { - StarSymbolToMSMultiFont *pConvert = 0; - FontFamily eFamily = FAMILY_DECORATIVE; - - if (!pConvert) - { - pConvert = CreateStarSymbolToMSMultiFont(); - } sal_Unicode cChar = rNumStr.GetChar(0); + StarSymbolToMSMultiFont *pConvert = CreateStarSymbolToMSMultiFont(); String sFont = pConvert->ConvertChar(cChar); + delete pConvert; if (sFont.Len()) { rNumStr = static_cast< sal_Unicode >(cChar | 0xF000); @@ -1366,7 +1361,6 @@ static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, Str let words own font substitution kick in */ rChrSet = RTL_TEXTENCODING_UNICODE; - eFamily = FAMILY_SWISS; rFontName = ::GetFontToken(rFontName, 0); } else @@ -1379,7 +1373,6 @@ static void lcl_SubstituteBullet(String& rNumStr, rtl_TextEncoding& rChrSet, Str rFontName.AssignAscii(RTL_CONSTASCII_STRINGPARAM("Wingdings")); rNumStr = static_cast< sal_Unicode >(0x6C); } - delete pConvert; } sal_Unicode DrawingML::SubstituteBullet( sal_Unicode cBulletId, ::com::sun::star::awt::FontDescriptor& rFontDesc ) diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx index 2495305d1c35..27ccbdb67c61 100644 --- a/oox/source/ole/axcontrol.cxx +++ b/oox/source/ole/axcontrol.cxx @@ -210,6 +210,16 @@ enum ApiTransparencyMode // ---------------------------------------------------------------------------- +/** Specifies how a form control supports the DefaultState property. */ +enum ApiDefaultStateMode +{ + API_DEFAULTSTATE_BOOLEAN, /// Control does not support tri-state, state is given as boolean. + API_DEFAULTSTATE_SHORT, /// Control does not support tri-state, state is given as short. + API_DEFAULTSTATE_TRISTATE /// Control supports tri-state, state is given as short. +}; + +// ---------------------------------------------------------------------------- + /** Converts the AX background formatting to UNO properties. */ void lclConvertBackground( AxControlHelper& rHelper, PropertyMap& rPropMap, sal_uInt32 nBackColor, sal_uInt32 nFlags, ApiTransparencyMode eTranspMode ) { @@ -325,8 +335,11 @@ void lclConvertPicture( AxControlHelper& rHelper, PropertyMap& rPropMap, const S // ---------------------------------------------------------------------------- /** Converts the AX value for checked/unchecked/dontknow to UNO properties. */ -void lclConvertState( AxControlHelper& /*rHelper*/, PropertyMap& rPropMap, const OUString& rValue, sal_Int32 nMultiSelect, bool bSupportsTriState ) +void lclConvertState( AxControlHelper& /*rHelper*/, PropertyMap& rPropMap, const OUString& rValue, sal_Int32 nMultiSelect, ApiDefaultStateMode eDefStateMode ) { + bool bBooleanState = eDefStateMode == API_DEFAULTSTATE_BOOLEAN; + bool bSupportsTriState = eDefStateMode == API_DEFAULTSTATE_TRISTATE; + // state sal_Int16 nState = bSupportsTriState ? API_STATE_DONTKNOW : API_STATE_UNCHECKED; if( rValue.getLength() == 1 ) switch( rValue[ 0 ] ) @@ -335,7 +348,10 @@ void lclConvertState( AxControlHelper& /*rHelper*/, PropertyMap& rPropMap, const case '1': nState = API_STATE_CHECKED; break; // any other string (also empty) means 'dontknow' } - rPropMap.setProperty( PROP_DefaultState, nState ); + if( bBooleanState ) + rPropMap.setProperty( PROP_DefaultState, nState != API_STATE_UNCHECKED ); + else + rPropMap.setProperty( PROP_DefaultState, nState ); // tristate if( bSupportsTriState ) @@ -698,6 +714,7 @@ void AxToggleButtonModel::convertProperties( AxControlHelper& rHelper, PropertyM rPropMap.setProperty( PROP_Toggle, true ); lclConvertBackground( rHelper, rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED ); lclConvertPicture( rHelper, rPropMap, maPictureData, mnPicturePos ); + lclConvertState( rHelper, rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_BOOLEAN ); AxMorphDataModel::convertProperties( rHelper, rPropMap ); } @@ -721,7 +738,7 @@ void AxCheckBoxModel::convertProperties( AxControlHelper& rHelper, PropertyMap& lclConvertBackground( rHelper, rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID ); lclConvertVisualEffect( rHelper, rPropMap, mnSpecialEffect ); lclConvertPicture( rHelper, rPropMap, maPictureData, mnPicturePos ); - lclConvertState( rHelper, rPropMap, maValue, mnMultiSelect, true ); + lclConvertState( rHelper, rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_TRISTATE ); AxMorphDataModel::convertProperties( rHelper, rPropMap ); } @@ -745,7 +762,7 @@ void AxOptionButtonModel::convertProperties( AxControlHelper& rHelper, PropertyM lclConvertBackground( rHelper, rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID ); lclConvertVisualEffect( rHelper, rPropMap, mnSpecialEffect ); lclConvertPicture( rHelper, rPropMap, maPictureData, mnPicturePos ); - lclConvertState( rHelper, rPropMap, maValue, mnMultiSelect, false ); + lclConvertState( rHelper, rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_SHORT ); AxMorphDataModel::convertProperties( rHelper, rPropMap ); } diff --git a/oox/source/xls/biffhelper.cxx b/oox/source/xls/biffhelper.cxx index a12909ed9ef0..c9d125ae6a54 100644 --- a/oox/source/xls/biffhelper.cxx +++ b/oox/source/xls/biffhelper.cxx @@ -122,19 +122,27 @@ struct CodePageEntry_TEPred // ---------------------------------------------------------------------------- -bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue ) +union DecodedDouble +{ + double mfValue; + sal_math_Double maStruct; + + inline explicit DecodedDouble() {} + inline explicit DecodedDouble( double fValue ) : mfValue( fValue ) {} +}; + +bool lclCalcRkFromDouble( sal_Int32& ornRkValue, const DecodedDouble& rDecDbl ) { // double - const sal_math_Double* pValue = reinterpret_cast< const sal_math_Double* >( &fValue ); - if( (pValue->w32_parts.lsw == 0) && ((pValue->w32_parts.msw & 0x3) == 0) ) + if( (rDecDbl.maStruct.w32_parts.lsw == 0) && ((rDecDbl.maStruct.w32_parts.msw & 0x3) == 0) ) { - ornRkValue = static_cast< sal_Int32 >( pValue->w32_parts.msw ); + ornRkValue = static_cast< sal_Int32 >( rDecDbl.maStruct.w32_parts.msw ); return true; } // integer double fInt = 0.0; - double fFrac = modf( fValue, &fInt ); + double fFrac = modf( rDecDbl.mfValue, &fInt ); if( (fFrac == 0.0) && (-536870912.0 <= fInt) && (fInt <= 536870911.0) ) // 2^29 { ornRkValue = static_cast< sal_Int32 >( fInt ); @@ -146,6 +154,22 @@ bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue ) return false; } +bool lclCalcRkFromDouble( sal_Int32& ornRkValue, double fValue ) +{ + DecodedDouble aDecDbl( fValue ); + if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) ) + return true; + + aDecDbl.mfValue *= 100.0; + if( lclCalcRkFromDouble( ornRkValue, aDecDbl ) ) + { + ornRkValue |= BIFF_RK_100FLAG; + return true; + } + + return false; +} + // ---------------------------------------------------------------------------- void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, sal_Int32 nBytes, BiffType eBiff ) @@ -232,23 +256,22 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, /*static*/ double BiffHelper::calcDoubleFromRk( sal_Int32 nRkValue ) { - double fValue = 0.0; + DecodedDouble aDecDbl( 0.0 ); if( getFlag( nRkValue, BIFF_RK_INTFLAG ) ) { sal_Int32 nTemp = nRkValue >> 2; setFlag< sal_Int32 >( nTemp, 0xE0000000, nRkValue < 0 ); - fValue = nTemp; + aDecDbl.mfValue = nTemp; } else { - sal_math_Double* pDouble = reinterpret_cast< sal_math_Double* >( &fValue ); - pDouble->w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK ); + aDecDbl.maStruct.w32_parts.msw = static_cast< sal_uInt32 >( nRkValue & BIFF_RK_VALUEMASK ); } if( getFlag( nRkValue, BIFF_RK_100FLAG ) ) - fValue /= 100.0; + aDecDbl.mfValue /= 100.0; - return fValue; + return aDecDbl.mfValue; } /*static*/ bool BiffHelper::calcRkFromDouble( sal_Int32& ornRkValue, double fValue ) @@ -279,10 +302,10 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, case BIFF_ERR_NA: nApiError = 0x7FFF; break; default: OSL_ENSURE( false, "BiffHelper::calcDoubleFromError - unknown error code" ); } - double fValue; - ::rtl::math::setNan( &fValue ); - reinterpret_cast< sal_math_Double* >( &fValue )->nan_parts.fraction_lo = nApiError; - return fValue; + DecodedDouble aDecDbl; + ::rtl::math::setNan( &aDecDbl.mfValue ); + aDecDbl.maStruct.nan_parts.fraction_lo = nApiError; + return aDecDbl.mfValue; } /*static*/ rtl_TextEncoding BiffHelper::calcTextEncodingFromCodePage( sal_uInt16 nCodePage ) @@ -312,15 +335,14 @@ void lclImportImgDataDib( StreamDataSequence& orDataSeq, BiffInputStream& rStrm, sal_uInt16 nFormat, nEnv; sal_Int32 nBytes; rStrm >> nFormat >> nEnv >> nBytes; - OSL_ENSURE( (nFormat == BIFF_IMGDATA_WMF) || (nFormat == BIFF_IMGDATA_DIB) || (nFormat == BIFF_IMGDATA_NATIVE), "BiffHelper::importImgData - unknown format" ); OSL_ENSURE( nBytes > 0, "BiffHelper::importImgData - invalid data size" ); if( (0 < nBytes) && (nBytes <= rStrm.getRemaining()) ) { switch( nFormat ) { - case BIFF_IMGDATA_WMF: /* TODO */ break; +// case BIFF_IMGDATA_WMF: /* TODO */ break; case BIFF_IMGDATA_DIB: lclImportImgDataDib( orDataSeq, rStrm, nBytes, eBiff ); break; - case BIFF_IMGDATA_NATIVE: /* TODO */ break; +// case BIFF_IMGDATA_NATIVE: /* TODO */ break; default: OSL_ENSURE( false, "BiffHelper::importImgData - unknown image format" ); } } diff --git a/oox/source/xls/formulabase.cxx b/oox/source/xls/formulabase.cxx index 5240960f7a88..52da0e546506 100644 --- a/oox/source/xls/formulabase.cxx +++ b/oox/source/xls/formulabase.cxx @@ -232,12 +232,13 @@ const size_t FUNCINFO_PARAMINFOCOUNT = 5; /// Number of parameter const sal_uInt16 FUNCFLAG_VOLATILE = 0x0001; /// Result is volatile (e.g. NOW() function). const sal_uInt16 FUNCFLAG_IMPORTONLY = 0x0002; /// Only used in import filter. const sal_uInt16 FUNCFLAG_EXPORTONLY = 0x0004; /// Only used in export filter. -const sal_uInt16 FUNCFLAG_MACROCALL = 0x0008; /// Function is simulated by macro call in Excel. -const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0010; /// Function is external in Calc. -const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0020; /// Function is a macro-sheet function. -const sal_uInt16 FUNCFLAG_MACROCMD = 0x0040; /// Function is a macro-sheet command. -const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0080; /// Function is always represented by a tFuncVar token. -const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0100; /// Optional parameters are expected to appear in pairs. +const sal_uInt16 FUNCFLAG_MACROCALL = 0x0008; /// Function is stored as macro call in Excel (_xlfn. prefix). OOXML name MUST exist. +const sal_uInt16 FUNCFLAG_MACROCALLODF = 0x0010; /// ODF-only function stored as macro call in Excel (_xlfnodf. prefix). ODF name MUST exist. +const sal_uInt16 FUNCFLAG_EXTERNAL = 0x0020; /// Function is external in Calc. +const sal_uInt16 FUNCFLAG_MACROFUNC = 0x0040; /// Function is a macro-sheet function. +const sal_uInt16 FUNCFLAG_MACROCMD = 0x0080; /// Function is a macro-sheet command. +const sal_uInt16 FUNCFLAG_ALWAYSVAR = 0x0100; /// Function is always represented by a tFuncVar token. +const sal_uInt16 FUNCFLAG_PARAMPAIRS = 0x0200; /// Optional parameters are expected to appear in pairs. const sal_uInt16 FUNCFLAG_FUNCLIBMASK = 0xF000; /// Mask for function library bits. const sal_uInt16 FUNCFLAG_EUROTOOL = 0x1000; /// Function is part of the EuroTool add-in. @@ -349,7 +350,6 @@ static const FunctionData saFuncTableBiff2[] = { "TREND", "TREND", 50, 50, 1, 3, A, { RA, RA, RA, C }, 0 }, { "LOGEST", "LOGEST", 51, 51, 1, 2, A, { RA, RA, C, C }, 0 }, { "GROWTH", "GROWTH", 52, 52, 1, 3, A, { RA, RA, RA, C }, 0 }, - { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC }, { "PV", "PV", 56, 56, 3, 5, V, { VR }, 0 }, { "FV", "FV", 57, 57, 3, 5, V, { VR }, 0 }, { "NPER", "NPER", 58, 58, 3, 5, V, { VR }, 0 }, @@ -373,11 +373,9 @@ static const FunctionData saFuncTableBiff2[] = { "ROWS", "ROWS", 76, 76, 1, 1, V, { RO }, 0 }, { "COLUMNS", "COLUMNS", 77, 77, 1, 1, V, { RO }, 0 }, { "OFFSET", "OFFSET", 78, 78, 3, 5, R, { RO, VR }, FUNCFLAG_VOLATILE }, - { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC }, { "SEARCH", "SEARCH", 82, 82, 2, 3, V, { VR }, 0 }, { "TRANSPOSE", "TRANSPOSE", 83, 83, 1, 1, A, { VO }, 0 }, { "TYPE", "TYPE", 86, 86, 1, 1, V, { VX }, 0 }, - { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC }, { "ATAN2", "ATAN2", 97, 97, 2, 2, V, { VR }, 0 }, { "ASIN", "ASIN", 98, 98, 1, 1, V, { VR }, 0 }, { "ACOS", "ACOS", 99, 99, 1, 1, V, { VR }, 0 }, @@ -411,9 +409,6 @@ static const FunctionData saFuncTableBiff2[] = { "SYD", "SYD", 143, 143, 4, 4, V, { VR }, 0 }, { "DDB", "DDB", 144, 144, 4, 5, V, { VR }, 0 }, { "INDIRECT", "INDIRECT", 148, 148, 1, 2, R, { VR }, FUNCFLAG_VOLATILE }, - { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, - { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, - { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, { "CLEAN", "CLEAN", 162, 162, 1, 1, V, { VR }, 0 }, { "MDETERM", "MDETERM", 163, 163, 1, 1, V, { VA }, 0 }, { "MINVERSE", "MINVERSE", 164, 164, 1, 1, A, { VA }, 0 }, @@ -437,10 +432,16 @@ static const FunctionData saFuncTableBiff2[] = // *** macro sheet commands *** { 0, "A1.R1C1", 30, 30, 0, 1, V, { VR }, FUNCFLAG_MACROCMD }, + { 0, "RETURN", 55, 55, 0, 1, R, { RO }, FUNCFLAG_MACROFUNC }, + { 0, "ABSREF", 79, 79, 2, 2, R, { VR, RO }, FUNCFLAG_MACROFUNC }, { 0, "ADD.ARROW", 81, 81, 0, 0, V, {}, FUNCFLAG_MACROCMD }, + { 0, "ACTIVE.CELL", 94, 94, 0, 0, R, {}, FUNCFLAG_MACROFUNC }, { 0, "ACTIVATE", 103, 103, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, { 0, "ACTIVATE.NEXT", 104, 104, 0, 0, V, {}, FUNCFLAG_MACROCMD }, - { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD } + { 0, "ACTIVATE.PREV", 105, 105, 0, 0, V, {}, FUNCFLAG_MACROCMD }, + { 0, "ADD.BAR", 151, 151, 0, 0, V, {}, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, + { 0, "ADD.MENU", 152, 152, 2, 2, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR }, + { 0, "ADD.COMMAND", 153, 153, 3, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC | FUNCFLAG_ALWAYSVAR } }; /** Functions new in BIFF3. */ @@ -450,9 +451,6 @@ static const FunctionData saFuncTableBiff3[] = { "TREND", "TREND", 50, 50, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 { "LOGEST", "LOGEST", 51, 51, 1, 4, A, { RA, RA, VV }, 0 }, // BIFF2: 1-2, BIFF3: 1-4 { "GROWTH", "GROWTH", 52, 52, 1, 4, A, { RA, RA, RA, VV }, 0 }, // BIFF2: 1-3, BIFF3: 1-4 - { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1 - { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3 - { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 3, BIFF3: 3-4 { "TRUNC", "TRUNC", 197, 197, 1, 2, V, { VR }, 0 }, // BIFF2: 1, BIFF3: 1-2 { "DOLLAR", "USDOLLAR", 204, 204, 1, 2, V, { VR }, FUNCFLAG_IMPORTONLY }, { 0/*"FIND"*/, "FINDB", 205, 205, 2, 3, V, { VR }, 0 }, @@ -481,7 +479,13 @@ static const FunctionData saFuncTableBiff3[] = { "ATANH", "ATANH", 234, 234, 1, 1, V, { VR }, 0 }, { "ACOTH", "ATANH", 234, 234, 1, 1, V, { VR }, FUNCFLAG_EXPORTONLY }, { "DGET", "DGET", 235, 235, 3, 3, V, { RO, RR }, 0 }, - { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE } + { "INFO", "INFO", 244, 244, 1, 1, V, { VR }, FUNCFLAG_VOLATILE }, + + // *** macro sheet commands *** + + { 0, "ADD.BAR", 151, 151, 0, 1, V, { VR }, FUNCFLAG_MACROFUNC }, // BIFF2: 0, BIFF3: 0-1 + { 0, "ADD.MENU", 152, 152, 2, 3, V, { VR, RO }, FUNCFLAG_MACROFUNC }, // BIFF2: 2, BIFF3: 2-3 + { 0, "ADD.COMMAND", 153, 153, 3, 4, V, { VR, RO }, FUNCFLAG_MACROFUNC } // BIFF2: 3, BIFF3: 3-4 }; /** Functions new in BIFF4. */ @@ -665,8 +669,6 @@ static const FunctionData saFuncTableBiff5[] = { "WEEKDAY", "WEEKDAY", 70, 70, 1, 2, V, { VR }, 0 }, // BIFF2-4: 1, BIFF5: 1-2 { "HLOOKUP", "HLOOKUP", 101, 101, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 { "VLOOKUP", "VLOOKUP", 102, 102, 3, 4, V, { VV, RO, RO, VV }, 0 }, // BIFF2-4: 3, BIFF5: 3-4 - { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4 - { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5 { "DAYS360", "DAYS360", 220, 220, 2, 3, V, { VR }, 0 }, // BIFF3-4: 2, BIFF5: 2-3 { 0, "EXTERN.CALL", 255, 255, 1, MX, R, { RO_E, RO }, FUNCFLAG_EXPORTONLY }, // MACRO or EXTERNAL { "CONCATENATE", "CONCATENATE", 336, 336, 0, MX, V, { VR }, 0 }, @@ -689,6 +691,8 @@ static const FunctionData saFuncTableBiff5[] = // *** macro sheet commands *** + { 0, "ADD.MENU", 152, 152, 2, 4, V, { VR, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 2-3, BIFF5: 2-4 + { 0, "ADD.COMMAND", 153, 153, 3, 5, V, { VR, RO, RO, RO, VR }, FUNCFLAG_MACROFUNC }, // BIFF3-4: 3-4, BIFF5: 3-5 { 0, "ADD.CHART.AUTOFORMAT", 390, 390, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, { 0, "ADD.LIST.ITEM", 451, 451, 0, 2, V, { VR }, FUNCFLAG_MACROCMD }, { 0, "ACTIVE.CELL.FONT", 476, 476, 0, 14, V, { VR }, FUNCFLAG_MACROCMD } @@ -741,41 +745,39 @@ static const FunctionData saFuncTableOox[] = /** Functions defined by OpenFormula, but not supported by Calc or by Excel. */ static const FunctionData saFuncTableOdf[] = { - { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, - { "B", 0, NOID, NOID, 3, 4, V, { VR }, 0 }, - { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, 0 }, - { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, 0 }, - { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "DDE", 0, NOID, NOID, 3, 4, V, { VR }, 0 }, - { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, 0 }, - { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, 0 }, - { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, 0 }, - { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, - { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, - { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, 0 }, - { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, 0 }, - { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, 0 }, - { "MULTIPLE.OPERATIONS", 0, NOID, NOID, 3, 5, V, { RO }, 0 }, - { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, 0 }, - { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, 0 }, - { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, 0 }, - { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, - { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, 0 }, - { "SHEET", 0, NOID, NOID, 1, 1, V, { RO }, 0 }, - { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, 0 }, - { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, 0 }, - { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, - { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, 0 }, - { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, 0 } + { "ARABIC", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "B", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "BASE", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "BITAND", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "BITLSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "BITOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "BITRSHIFT", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "BITXOR", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "CHISQDIST", 0, NOID, NOID, 2, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "CHISQINV", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "COMBINA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "DAYS", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "DECIMAL", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "FDIST", 0, NOID, NOID, 3, 4, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "FINV", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "FORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, + { "GAMMA", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "GAUSS", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "IFNA", 0, NOID, NOID, 2, 2, V, { VR, RO }, FUNCFLAG_MACROCALLODF }, + { "ISFORMULA", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, + { "ISOWEEKNUM", 0, NOID, NOID, 1, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "MUNIT", 0, NOID, NOID, 1, 1, A, { VR }, FUNCFLAG_MACROCALLODF }, + { "NUMBERVALUE", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "PDURATION", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "PERMUTATIONA", 0, NOID, NOID, 2, 2, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "PHI", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "RRI", 0, NOID, NOID, 3, 3, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "SHEET", 0, NOID, NOID, 1, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, + { "SHEETS", 0, NOID, NOID, 0, 1, V, { RO }, FUNCFLAG_MACROCALLODF }, + { "SKEWP", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF }, + { "UNICHAR", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "UNICODE", 0, NOID, NOID, 1, 1, V, { VR }, FUNCFLAG_MACROCALLODF }, + { "XOR", 0, NOID, NOID, 1, MX, V, { RX }, FUNCFLAG_MACROCALLODF } }; // ---------------------------------------------------------------------------- @@ -898,6 +900,7 @@ FunctionProviderImpl::FunctionProviderImpl( FilterType eFilter, BiffType eBiff, initFuncs( saFuncTableBiff8, STATIC_ARRAY_END( saFuncTableBiff8 ), nMaxParam, bImportFilter ); if( eFilter == FILTER_OOX ) initFuncs( saFuncTableOox, STATIC_ARRAY_END( saFuncTableOox ), nMaxParam, bImportFilter ); + initFuncs( saFuncTableOdf, STATIC_ARRAY_END( saFuncTableOdf ), nMaxParam, bImportFilter ); } void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nMaxParam ) @@ -908,13 +911,25 @@ void FunctionProviderImpl::initFunc( const FunctionData& rFuncData, sal_uInt8 nM xFuncInfo->maOdfFuncName = OUString::createFromAscii( rFuncData.mpcOdfFuncName ); if( rFuncData.mpcOoxFuncName ) xFuncInfo->maOoxFuncName = OUString::createFromAscii( rFuncData.mpcOoxFuncName ); + if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALL ) ) + { + OSL_ENSURE( xFuncInfo->maOoxFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing OOXML function name" ); + OSL_ENSURE( !getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ), "FunctionProviderImpl::initFunc - unexpected flag FUNCFLAG_MACROCALLODF" ); xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfn." ) + xFuncInfo->maOoxFuncName; + } + else if( getFlag( rFuncData.mnFlags, FUNCFLAG_MACROCALLODF ) ) + { + OSL_ENSURE( xFuncInfo->maOdfFuncName.getLength() > 0, "FunctionProviderImpl::initFunc - missing ODF function name" ); + xFuncInfo->maBiffMacroName = CREATE_OUSTRING( "_xlfnodf." ) + xFuncInfo->maOdfFuncName; + } + switch( rFuncData.mnFlags & FUNCFLAG_FUNCLIBMASK ) { case FUNCFLAG_EUROTOOL: xFuncInfo->meFuncLibType = FUNCLIB_EUROTOOL; break; default: xFuncInfo->meFuncLibType = FUNCLIB_UNKNOWN; } + xFuncInfo->mnApiOpCode = -1; xFuncInfo->mnOobFuncId = rFuncData.mnOobFuncId; xFuncInfo->mnBiffFuncId = rFuncData.mnBiffFuncId; diff --git a/oox/source/xls/stylesbuffer.cxx b/oox/source/xls/stylesbuffer.cxx index 3e69266592c7..37726277cc3f 100644 --- a/oox/source/xls/stylesbuffer.cxx +++ b/oox/source/xls/stylesbuffer.cxx @@ -73,6 +73,7 @@ using ::com::sun::star::awt::FontDescriptor; using ::com::sun::star::awt::XDevice; using ::com::sun::star::awt::XFont2; using ::com::sun::star::table::BorderLine; +using ::com::sun::star::table::TableBorder; using ::com::sun::star::text::XText; using ::com::sun::star::style::XStyle; using ::oox::core::FilterBase; @@ -1402,7 +1403,6 @@ void Alignment::writeToPropertyMap( PropertyMap& rPropMap ) const rPropMap[ PROP_VertJustify ] <<= maApiData.meVerJustify; rPropMap[ PROP_WritingMode ] <<= maApiData.mnWritingMode; rPropMap[ PROP_RotateAngle ] <<= maApiData.mnRotation; - rPropMap[ PROP_RotateReference ] <<= ::com::sun::star::table::CellVertJustify_STANDARD; // rotation reference rPropMap[ PROP_Orientation ] <<= maApiData.meOrientation; rPropMap[ PROP_ParaIndent ] <<= maApiData.mnIndent; rPropMap[ PROP_IsTextWrapped ] <<= maApiData.mbWrapText; @@ -1521,6 +1521,57 @@ ApiBorderData::ApiBorderData() : { } +bool ApiBorderData::hasAnyOuterBorder() const +{ + return + (maBorder.IsTopLineValid && (maBorder.TopLine.OuterLineWidth > 0)) || + (maBorder.IsBottomLineValid && (maBorder.BottomLine.OuterLineWidth > 0)) || + (maBorder.IsLeftLineValid && (maBorder.LeftLine.OuterLineWidth > 0)) || + (maBorder.IsRightLineValid && (maBorder.RightLine.OuterLineWidth > 0)); +} + +namespace { + +bool operator==( const BorderLine& rLeft, const BorderLine& rRight ) +{ + return + (rLeft.Color == rRight.Color) && + (rLeft.InnerLineWidth == rRight.InnerLineWidth) && + (rLeft.OuterLineWidth == rRight.OuterLineWidth) && + (rLeft.LineDistance == rRight.LineDistance); +} + +bool operator==( const TableBorder& rLeft, const TableBorder& rRight ) +{ + return + (rLeft.TopLine == rRight.TopLine) && + (rLeft.IsTopLineValid == rRight.IsTopLineValid) && + (rLeft.BottomLine == rRight.BottomLine) && + (rLeft.IsBottomLineValid == rRight.IsBottomLineValid) && + (rLeft.LeftLine == rRight.LeftLine) && + (rLeft.IsLeftLineValid == rRight.IsLeftLineValid) && + (rLeft.RightLine == rRight.RightLine) && + (rLeft.IsRightLineValid == rRight.IsRightLineValid) && + (rLeft.HorizontalLine == rRight.HorizontalLine) && + (rLeft.IsHorizontalLineValid == rRight.IsHorizontalLineValid) && + (rLeft.VerticalLine == rRight.VerticalLine) && + (rLeft.IsVerticalLineValid == rRight.IsVerticalLineValid) && + (rLeft.Distance == rRight.Distance) && + (rLeft.IsDistanceValid == rRight.IsDistanceValid); +} + +} // namespace + +bool operator==( const ApiBorderData& rLeft, const ApiBorderData& rRight ) +{ + return + (rLeft.maBorder == rRight.maBorder) && + (rLeft.maTLtoBR == rRight.maTLtoBR) && + (rLeft.maBLtoTR == rRight.maBLtoTR) && + (rLeft.mbBorderUsed == rRight.mbBorderUsed) && + (rLeft.mbDiagUsed == rRight.mbDiagUsed); +} + // ============================================================================ namespace { @@ -1824,6 +1875,14 @@ ApiSolidFillData::ApiSolidFillData() : { } +bool operator==( const ApiSolidFillData& rLeft, const ApiSolidFillData& rRight ) +{ + return + (rLeft.mnColor == rRight.mnColor) && + (rLeft.mbTransparent == rRight.mbTransparent) && + (rLeft.mbUsed == rRight.mbUsed); +} + // ============================================================================ namespace { @@ -2136,7 +2195,8 @@ XfModel::XfModel() : Xf::Xf( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ), maAlignment( rHelper ), - maProtection( rHelper ) + maProtection( rHelper ), + meRotationRef( ::com::sun::star::table::CellVertJustify_STANDARD ) { } @@ -2319,13 +2379,46 @@ void Xf::importXf( BiffInputStream& rStrm ) void Xf::finalizeImport() { + StylesBuffer& rStyles = getStyles(); + // alignment and protection maAlignment.finalizeImport(); maProtection.finalizeImport(); - // update used flags from cell style - if( maModel.mbCellXf ) - if( const Xf* pStyleXf = getStyles().getStyleXf( maModel.mnStyleXfId ).get() ) - updateUsedFlags( *pStyleXf ); + + /* Enables the used flags, if the formatting attributes differ from the + style XF. In cell XFs Excel uses the cell attributes, if they differ + from the parent style XF (even if the used flag is switched off). + #109899# ...or if the respective flag is not set in parent style XF. + */ + const Xf* pStyleXf = isCellXf() ? rStyles.getStyleXf( maModel.mnStyleXfId ).get() : 0; + if( pStyleXf ) + { + const XfModel& rStyleData = pStyleXf->maModel; + if( !maModel.mbFontUsed ) + maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId); + if( !maModel.mbNumFmtUsed ) + maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId); + if( !maModel.mbAlignUsed ) + maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == pStyleXf->maAlignment.getApiData()); + if( !maModel.mbProtUsed ) + maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == pStyleXf->maProtection.getApiData()); + if( !maModel.mbBorderUsed ) + maModel.mbBorderUsed = !rStyleData.mbBorderUsed || !rStyles.equalBorders( maModel.mnBorderId, rStyleData.mnBorderId ); + if( !maModel.mbAreaUsed ) + maModel.mbAreaUsed = !rStyleData.mbAreaUsed || !rStyles.equalFills( maModel.mnFillId, rStyleData.mnFillId ); + } + + /* #i38709# Decide which rotation reference mode to use. If any outer + border line of the cell is set (either explicitly or via cell style), + and the cell contents are rotated, set rotation reference to bottom of + cell. This causes the borders to be painted rotated with the text. */ + if( const Alignment* pAlignment = maModel.mbAlignUsed ? &maAlignment : (pStyleXf ? &pStyleXf->maAlignment : 0) ) + { + sal_Int32 nBorderId = maModel.mbBorderUsed ? maModel.mnBorderId : (pStyleXf ? pStyleXf->maModel.mnBorderId : -1); + if( const Border* pBorder = rStyles.getBorder( nBorderId ).get() ) + if( (pAlignment->getApiData().mnRotation != 0) && pBorder->getApiData().hasAnyOuterBorder() ) + meRotationRef = ::com::sun::star::table::CellVertJustify_BOTTOM; + } } FontRef Xf::getFont() const @@ -2345,7 +2438,7 @@ void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const StylesBuffer& rStyles = getStyles(); // create and set cell style - if( maModel.mbCellXf ) + if( isCellXf() ) rPropMap[ PROP_CellStyle ] <<= rStyles.createCellStyle( maModel.mnStyleXfId ); if( maModel.mbFontUsed ) @@ -2360,6 +2453,8 @@ void Xf::writeToPropertyMap( PropertyMap& rPropMap ) const rStyles.writeBorderToPropertyMap( rPropMap, maModel.mnBorderId ); if( maModel.mbAreaUsed ) rStyles.writeFillToPropertyMap( rPropMap, maModel.mnFillId ); + if( maModel.mbAlignUsed || maModel.mbBorderUsed ) + rPropMap[ PROP_RotateReference ] <<= meRotationRef; } void Xf::writeToPropertySet( PropertySet& rPropSet ) const @@ -2375,37 +2470,15 @@ void Xf::setBiffUsedFlags( sal_uInt8 nUsedFlags ) - In cell XFs a *set* bit means a used attribute. - In style XFs a *cleared* bit means a used attribute. The boolean flags always store true, if the attribute is used. - The "maModel.mbCellXf == getFlag(...)" construct evaluates to true in - both mentioned cases: cell XF and set bit; or style XF and cleared bit. - */ - maModel.mbFontUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_FONT_USED ); - maModel.mbNumFmtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED ); - maModel.mbAlignUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED ); - maModel.mbProtUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_PROT_USED ); - maModel.mbBorderUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_BORDER_USED ); - maModel.mbAreaUsed = maModel.mbCellXf == getFlag( nUsedFlags, BIFF_XF_AREA_USED ); -} - -void Xf::updateUsedFlags( const Xf& rStyleXf ) -{ - /* Enables the used flags, if the formatting attributes differ from the - passed style XF. In cell XFs Excel uses the cell attributes, if they - differ from the parent style XF. - #109899# ...or if the respective flag is not set in parent style XF. + The "isCellXf() == getFlag(...)" construct evaluates to true in both + mentioned cases: cell XF and set bit; or style XF and cleared bit. */ - const XfModel& rStyleData = rStyleXf.maModel; - if( !maModel.mbFontUsed ) - maModel.mbFontUsed = !rStyleData.mbFontUsed || (maModel.mnFontId != rStyleData.mnFontId); - if( !maModel.mbNumFmtUsed ) - maModel.mbNumFmtUsed = !rStyleData.mbNumFmtUsed || (maModel.mnNumFmtId != rStyleData.mnNumFmtId); - if( !maModel.mbAlignUsed ) - maModel.mbAlignUsed = !rStyleData.mbAlignUsed || !(maAlignment.getApiData() == rStyleXf.maAlignment.getApiData()); - if( !maModel.mbProtUsed ) - maModel.mbProtUsed = !rStyleData.mbProtUsed || !(maProtection.getApiData() == rStyleXf.maProtection.getApiData()); - if( !maModel.mbBorderUsed ) - maModel.mbBorderUsed = !rStyleData.mbBorderUsed || (maModel.mnBorderId != rStyleData.mnBorderId); - if( !maModel.mbAreaUsed ) - maModel.mbAreaUsed = !rStyleData.mbAreaUsed || (maModel.mnFillId != rStyleData.mnFillId); + maModel.mbFontUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_FONT_USED ); + maModel.mbNumFmtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_NUMFMT_USED ); + maModel.mbAlignUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_ALIGN_USED ); + maModel.mbProtUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_PROT_USED ); + maModel.mbBorderUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_BORDER_USED ); + maModel.mbAreaUsed = isCellXf() == getFlag( nUsedFlags, BIFF_XF_AREA_USED ); } // ============================================================================ @@ -3137,11 +3210,12 @@ void StylesBuffer::importFormat( BiffInputStream& rStrm ) void StylesBuffer::importXf( BiffInputStream& rStrm ) { XfRef xXf( new Xf( *this ) ); - // store XF in both lists (except BIFF2 which does not support cell styles) - maCellXfs.push_back( xXf ); - if( getBiff() != BIFF2 ) - maStyleXfs.push_back( xXf ); xXf->importXf( rStrm ); + + XfRef xCellXf, xStyleXf; + (xXf->isCellXf() ? xCellXf : xStyleXf) = xXf; + maCellXfs.push_back( xCellXf ); + maStyleXfs.push_back( xStyleXf ); } void StylesBuffer::importStyle( BiffInputStream& rStrm ) @@ -3160,20 +3234,11 @@ void StylesBuffer::finalizeImport() // borders and fills maBorders.forEachMem( &Border::finalizeImport ); maFills.forEachMem( &Fill::finalizeImport ); - - /* Style XFs and cell XFs. The BIFF format stores cell XFs and style XFs - mixed in a single list. The import filter has stored the XFs in both - lists to make the getStyleXf() function working correctly (e.g. for - retrieving the default font, see getDefaultFont() function), except for - BIFF2 which does not support cell styles at all. Therefore, if in BIFF - filter mode, we do not need to finalize the cell styles list. */ - if( getFilterType() == FILTER_OOX ) - maStyleXfs.forEachMem( &Xf::finalizeImport ); + // style XFs and cell XFs + maStyleXfs.forEachMem( &Xf::finalizeImport ); maCellXfs.forEachMem( &Xf::finalizeImport ); - // built-in and user defined cell styles maCellStyles.finalizeImport(); - // differential formatting (for conditional formatting) maDxfs.forEachMem( &Dxf::finalizeImport ); } @@ -3188,6 +3253,11 @@ FontRef StylesBuffer::getFont( sal_Int32 nFontId ) const return maFonts.get( nFontId ); } +BorderRef StylesBuffer::getBorder( sal_Int32 nBorderId ) const +{ + return maBorders.get( nBorderId ); +} + XfRef StylesBuffer::getCellXf( sal_Int32 nXfId ) const { return maCellXfs.get( nXfId ); @@ -3229,6 +3299,56 @@ const FontModel& StylesBuffer::getDefaultFontModel() const return xDefFont.get() ? xDefFont->getModel() : getTheme().getDefaultFontModel(); } +bool StylesBuffer::equalBorders( sal_Int32 nBorderId1, sal_Int32 nBorderId2 ) const +{ + if( nBorderId1 == nBorderId2 ) + return true; + + switch( getFilterType() ) + { + case FILTER_OOX: + // in OOXML, borders are assumed to be unique + return false; + + case FILTER_BIFF: + { + // in BIFF, a new border entry has been created for every XF + const Border* pBorder1 = maBorders.get( nBorderId1 ).get(); + const Border* pBorder2 = maBorders.get( nBorderId2 ).get(); + return pBorder1 && pBorder2 && (pBorder1->getApiData() == pBorder2->getApiData()); + } + + case FILTER_UNKNOWN: + break; + } + return false; +} + +bool StylesBuffer::equalFills( sal_Int32 nFillId1, sal_Int32 nFillId2 ) const +{ + if( nFillId1 == nFillId2 ) + return true; + + switch( getFilterType() ) + { + case FILTER_OOX: + // in OOXML, fills are assumed to be unique + return false; + + case FILTER_BIFF: + { + // in BIFF, a new fill entry has been created for every XF + const Fill* pFill1 = maFills.get( nFillId1 ).get(); + const Fill* pFill2 = maFills.get( nFillId2 ).get(); + return pFill1 && pFill2 && (pFill1->getApiData() == pFill2->getApiData()); + } + + case FILTER_UNKNOWN: + break; + } + return false; +} + OUString StylesBuffer::getDefaultStyleName() const { return maCellStyles.getDefaultStyleName(); diff --git a/oox/source/xls/viewsettings.cxx b/oox/source/xls/viewsettings.cxx index 2d53541b404c..11cefa285444 100644 --- a/oox/source/xls/viewsettings.cxx +++ b/oox/source/xls/viewsettings.cxx @@ -56,7 +56,7 @@ 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::CellAddress; using ::oox::core::FilterBase; namespace oox { -- cgit