diff options
author | Daniel Rentz <dr@openoffice.org> | 2010-08-26 18:37:44 +0200 |
---|---|---|
committer | Daniel Rentz <dr@openoffice.org> | 2010-08-26 18:37:44 +0200 |
commit | 04c272eb8396e58376d2b61baee01c4a95f993b4 (patch) | |
tree | 489606116a897ec3c0186161269670b0e8c66146 | |
parent | 4d9f54e9f020c91c7fda048bcf3f7549d58bc2b4 (diff) |
dr77: #i114128# import legacy drawing controls
115 files changed, 3520 insertions, 1496 deletions
diff --git a/filter/inc/filter/msfilter/msvbahelper.hxx b/filter/inc/filter/msfilter/msvbahelper.hxx index 81607c9b296c..94ece293ee20 100644 --- a/filter/inc/filter/msfilter/msvbahelper.hxx +++ b/filter/inc/filter/msfilter/msvbahelper.hxx @@ -28,29 +28,81 @@ #define _MSVBAHELPER_HXX #include <sfx2/objsh.hxx> +#include <cppuhelper/implbase3.hxx> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/script/vba/XVBAMacroResolver.hpp> #include "filter/msfilter/msfilterdllapi.h" -namespace ooo { namespace vba +namespace ooo { +namespace vba { + +// ============================================================================ + +struct MSFILTER_DLLPUBLIC MacroResolvedInfo +{ + SfxObjectShell* mpDocContext; + String msResolvedMacro; + bool mbFound; + + inline explicit MacroResolvedInfo( SfxObjectShell* pDocContext = 0 ) : mpDocContext( pDocContext ), mbFound( false ) {} +}; + +MSFILTER_DLLPUBLIC String makeMacroURL( const String& sMacroName ); +MSFILTER_DLLPUBLIC ::rtl::OUString extractMacroName( const ::rtl::OUString& rMacroUrl ); +MSFILTER_DLLPUBLIC MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const ::rtl::OUString& rMacroName, bool bSearchGlobalTemplates = false ); +MSFILTER_DLLPUBLIC sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, com::sun::star::uno::Sequence< com::sun::star::uno::Any >& aArgs, com::sun::star::uno::Any& aRet, const com::sun::star::uno::Any& aCaller ); + +// ============================================================================ + +typedef ::cppu::WeakImplHelper3< + ::com::sun::star::lang::XServiceInfo, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::script::vba::XVBAMacroResolver > VBAMacroResolverBase; + +class VBAMacroResolver : public VBAMacroResolverBase { - class MSFILTER_DLLPUBLIC VBAMacroResolvedInfo - { - SfxObjectShell* mpDocContext; - bool mbFound; - String msResolvedMacro; - public: - VBAMacroResolvedInfo() : mpDocContext(NULL), mbFound( false ){} - void SetResolved( bool bRes ) { mbFound = bRes; } - bool IsResolved() { return mbFound; } - void SetMacroDocContext(SfxObjectShell* pShell ) { mpDocContext = pShell; } - SfxObjectShell* MacroDocContext() { return mpDocContext; } - String ResolvedMacro() { return msResolvedMacro; } - void SetResolvedMacro(const String& sMacro ) { msResolvedMacro = sMacro; } - }; - - MSFILTER_DLLPUBLIC String makeMacroURL( const String& sMacroName ); - MSFILTER_DLLPUBLIC ::rtl::OUString extractMacroName( const ::rtl::OUString& rMacroUrl ); - MSFILTER_DLLPUBLIC VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUString& sMod, bool bSearchGlobalTemplates = false ); - MSFILTER_DLLPUBLIC sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, com::sun::star::uno::Sequence< com::sun::star::uno::Any >& aArgs, com::sun::star::uno::Any& aRet, const com::sun::star::uno::Any& aCaller ); -} } +public: + explicit VBAMacroResolver(); + virtual ~VBAMacroResolver(); + + // com.sun.star.lang.XServiceInfo interface ------------------------------- + + virtual ::rtl::OUString SAL_CALL + getImplementationName() throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL + supportsService( const ::rtl::OUString& rService ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL + getSupportedServiceNames() throw (::com::sun::star::uno::RuntimeException); + + // com.sun.star.lang.XInitialization interface ---------------------------- + + virtual void SAL_CALL initialize( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& rArgs ) + throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // com.sun.star.script.vba.XVBAMacroResolver interface -------------------- + + virtual ::rtl::OUString SAL_CALL + resolveVBAMacroToScriptURL( const ::rtl::OUString& rVBAMacroName ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL + resolveScriptURLtoVBAMacro( const ::rtl::OUString& rScriptURL ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > mxModel; + SfxObjectShell* mpObjShell; + ::rtl::OUString maProjectName; +}; + +// ============================================================================ + +} // namespace vba +} // namespace ooo #endif diff --git a/filter/source/msfilter/makefile.mk b/filter/source/msfilter/makefile.mk index 7780529b5580..1a8d27d85097 100644 --- a/filter/source/msfilter/makefile.mk +++ b/filter/source/msfilter/makefile.mk @@ -43,16 +43,17 @@ SLOFILES= \ $(SLO)$/countryid.obj \ $(SLO)$/escherex.obj \ $(SLO)$/eschesdo.obj \ + $(SLO)$/mscodec.obj \ $(SLO)$/msdffimp.obj \ + $(SLO)$/msfiltertracer.obj \ + $(SLO)$/msocximex.obj \ $(SLO)$/msoleexp.obj \ + $(SLO)$/msvbahelper.obj \ $(SLO)$/msvbasic.obj \ - $(SLO)$/svxmsbas.obj \ - $(SLO)$/msocximex.obj \ - $(SLO)$/mscodec.obj \ - $(SLO)$/msfiltertracer.obj \ + $(SLO)$/services.obj \ $(SLO)$/svdfppt.obj \ - $(SLO)$/svxmsbas2.obj \ - $(SLO)$/msvbahelper.obj \ + $(SLO)$/svxmsbas.obj \ + $(SLO)$/svxmsbas2.obj SHL1TARGET= msfilter$(DLLPOSTFIX) SHL1IMPLIB= i$(TARGET) diff --git a/filter/source/msfilter/msvbahelper.cxx b/filter/source/msfilter/msvbahelper.cxx index 18ecc5ae6530..11cb07618821 100644 --- a/filter/source/msfilter/msvbahelper.cxx +++ b/filter/source/msfilter/msvbahelper.cxx @@ -36,12 +36,14 @@ #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentInfoSupplier.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> #include <tools/urlobj.hxx> #include <osl/file.hxx> using namespace ::com::sun::star; -namespace ooo { namespace vba { +namespace ooo { +namespace vba { const static rtl::OUString sUrlPart0 = rtl::OUString::createFromAscii( "vnd.sun.star.script:"); const static rtl::OUString sUrlPart1 = rtl::OUString::createFromAscii( "?language=Basic&location=document"); @@ -62,6 +64,16 @@ String makeMacroURL( const String& sMacroName ) return ::rtl::OUString(); } +::rtl::OUString trimMacroName( const ::rtl::OUString& rMacroName ) +{ + // the name may contain whitespaces and may be enclosed in apostrophs + ::rtl::OUString aMacroName = rMacroName.trim(); + sal_Int32 nMacroLen = aMacroName.getLength(); + if( (nMacroLen >= 2) && (aMacroName[ 0 ] == '\'') && (aMacroName[ nMacroLen - 1 ] == '\'') ) + aMacroName = aMacroName.copy( 1, nMacroLen - 2 ).trim(); + return aMacroName; +} + SfxObjectShell* findShellForUrl( const rtl::OUString& sMacroURLOrPath ) { SfxObjectShell* pFoundShell=NULL; @@ -191,26 +203,16 @@ void parseMacro( const rtl::OUString& sMacro, String& sContainer, String& sModul sProcedure = sMacro; } -VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUString& MacroName, bool bSearchGlobalTemplates ) +MacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUString& MacroName, bool bSearchGlobalTemplates ) { - VBAMacroResolvedInfo aRes; - if ( !pShell ) - return aRes; - aRes.SetMacroDocContext( pShell ); + if( !pShell ) + return MacroResolvedInfo(); // the name may be enclosed in apostrophs - ::rtl::OUString sMacroUrl = MacroName; - sal_Int32 nMacroLen = MacroName.getLength(); - if( (nMacroLen >= 2) && (MacroName[0] == '\'') && (MacroName[nMacroLen-1] == '\'') ) - sMacroUrl = MacroName.copy( 1, nMacroLen - 2 ); + ::rtl::OUString aMacroName = trimMacroName( MacroName ); // parse the macro name - sal_Int32 nDocSepIndex = sMacroUrl.indexOf( '!' ); - - String sContainer; - String sModule; - String sProcedure; - + sal_Int32 nDocSepIndex = aMacroName.indexOf( '!' ); if( nDocSepIndex > 0 ) { // macro specified by document name @@ -218,127 +220,123 @@ VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUStrin // recursively // assume for now that the document name is *this* document - String sDocUrlOrPath = sMacroUrl.copy( 0, nDocSepIndex ); - sMacroUrl = sMacroUrl.copy( nDocSepIndex + 1 ); + String sDocUrlOrPath = aMacroName.copy( 0, nDocSepIndex ); + aMacroName = aMacroName.copy( nDocSepIndex + 1 ); OSL_TRACE("doc search, current shell is 0x%x", pShell ); SfxObjectShell* pFoundShell = findShellForUrl( sDocUrlOrPath ); OSL_TRACE("doc search, after find, found shell is 0x%x", pFoundShell ); - aRes = resolveVBAMacro( pFoundShell, sMacroUrl ); + return resolveVBAMacro( pFoundShell, aMacroName ); } - else - { - // macro is contained in 'this' document ( or code imported from a template - // where that template is a global template or perhaps the template this - // document is created from ) - // macro format = Container.Module.Procedure - parseMacro( sMacroUrl, sContainer, sModule, sProcedure ); - uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY); - uno::Reference< container::XNameContainer > xPrjNameCache; - if ( xSF.is() ) - xPrjNameCache.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY ); + // macro is contained in 'this' document ( or code imported from a template + // where that template is a global template or perhaps the template this + // document is created from ) + + MacroResolvedInfo aRes( pShell ); - std::vector< rtl::OUString > sSearchList; + // macro format = Container.Module.Procedure + String sContainer, sModule, sProcedure; + parseMacro( aMacroName, sContainer, sModule, sProcedure ); + uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY); + uno::Reference< container::XNameContainer > xPrjNameCache; + if ( xSF.is() ) + xPrjNameCache.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY ); - if ( sContainer.Len() > 0 ) + std::vector< rtl::OUString > sSearchList; + + if ( sContainer.Len() > 0 ) + { + // get the Project associated with the Container + if ( xPrjNameCache.is() ) { - // get the Project associated with the Container - if ( xPrjNameCache.is() ) + if ( xPrjNameCache->hasByName( sContainer ) ) { - if ( xPrjNameCache->hasByName( sContainer ) ) - { - rtl::OUString sProject; - xPrjNameCache->getByName( sContainer ) >>= sProject; - sContainer = sProject; - } + rtl::OUString sProject; + xPrjNameCache->getByName( sContainer ) >>= sProject; + sContainer = sProject; } - sSearchList.push_back( sContainer ); // First Lib to search } - else + sSearchList.push_back( sContainer ); // First Lib to search + } + else + { + // Ok, if we have no Container specified then we need to search them in order, this document, template this document created from, global templates, + // get the name of Project/Library for 'this' document + rtl::OUString sThisProject; + BasicManager* pBasicMgr = pShell-> GetBasicManager(); + if ( pBasicMgr ) { - // Ok, if we have no Container specified then we need to search them in order, this document, template this document created from, global templates, - // get the name of Project/Library for 'this' document - rtl::OUString sThisProject; - BasicManager* pBasicMgr = pShell-> GetBasicManager(); - if ( pBasicMgr ) - { - if ( pBasicMgr->GetName().Len() ) - sThisProject = pBasicMgr->GetName(); - else // cater for the case where VBA is not enabled - sThisProject = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ); - } - sSearchList.push_back( sThisProject ); // First Lib to search - if ( xPrjNameCache.is() ) - { - // is this document created from a template? - uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( pShell->GetModel(), uno::UNO_QUERY_THROW ); - uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW ); - uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW ); + if ( pBasicMgr->GetName().Len() ) + sThisProject = pBasicMgr->GetName(); + else // cater for the case where VBA is not enabled + sThisProject = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Standard") ); + } + sSearchList.push_back( sThisProject ); // First Lib to search + if ( xPrjNameCache.is() ) + { + // is this document created from a template? + uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( pShell->GetModel(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentPropertiesSupplier > xDocPropSupp( xDocInfoSupp->getDocumentInfo(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentProperties > xDocProps( xDocPropSupp->getDocumentProperties(), uno::UNO_QUERY_THROW ); - rtl::OUString sCreatedFrom = xDocProps->getTemplateURL(); - if ( sCreatedFrom.getLength() ) + rtl::OUString sCreatedFrom = xDocProps->getTemplateURL(); + if ( sCreatedFrom.getLength() ) + { + INetURLObject aObj; + aObj.SetURL( sCreatedFrom ); + bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID; + rtl::OUString aURL; + if ( bIsURL ) + aURL = sCreatedFrom; + else { - INetURLObject aObj; - aObj.SetURL( sCreatedFrom ); - bool bIsURL = aObj.GetProtocol() != INET_PROT_NOT_VALID; - rtl::OUString aURL; - if ( bIsURL ) - aURL = sCreatedFrom; - else - { - osl::FileBase::getFileURLFromSystemPath( sCreatedFrom, aURL ); - aObj.SetURL( aURL ); - } - sCreatedFrom = aObj.GetLastName(); + osl::FileBase::getFileURLFromSystemPath( sCreatedFrom, aURL ); + aObj.SetURL( aURL ); } + sCreatedFrom = aObj.GetLastName(); + } - sal_Int32 nIndex = sCreatedFrom.lastIndexOf( '.' ); - if ( nIndex != -1 ) - sCreatedFrom = sCreatedFrom.copy( 0, nIndex ); + sal_Int32 nIndex = sCreatedFrom.lastIndexOf( '.' ); + if ( nIndex != -1 ) + sCreatedFrom = sCreatedFrom.copy( 0, nIndex ); - rtl::OUString sPrj; - if ( sCreatedFrom.getLength() && xPrjNameCache->hasByName( sCreatedFrom ) ) - { - xPrjNameCache->getByName( sCreatedFrom ) >>= sPrj; - // Make sure we don't double up with this project - if ( !sPrj.equals( sThisProject ) ) - sSearchList.push_back( sPrj ); - } + rtl::OUString sPrj; + if ( sCreatedFrom.getLength() && xPrjNameCache->hasByName( sCreatedFrom ) ) + { + xPrjNameCache->getByName( sCreatedFrom ) >>= sPrj; + // Make sure we don't double up with this project + if ( !sPrj.equals( sThisProject ) ) + sSearchList.push_back( sPrj ); + } - // get list of global template Names - uno::Sequence< rtl::OUString > sTemplateNames = xPrjNameCache->getElementNames(); - sal_Int32 nLen = sTemplateNames.getLength(); - for ( sal_Int32 index = 0; ( bSearchGlobalTemplates && index < nLen ); ++index ) - { + // get list of global template Names + uno::Sequence< rtl::OUString > sTemplateNames = xPrjNameCache->getElementNames(); + sal_Int32 nLen = sTemplateNames.getLength(); + for ( sal_Int32 index = 0; ( bSearchGlobalTemplates && index < nLen ); ++index ) + { - if ( !sCreatedFrom.equals( sTemplateNames[ index ] ) ) + if ( !sCreatedFrom.equals( sTemplateNames[ index ] ) ) + { + if ( xPrjNameCache->hasByName( sTemplateNames[ index ] ) ) { - if ( xPrjNameCache->hasByName( sTemplateNames[ index ] ) ) - { - xPrjNameCache->getByName( sTemplateNames[ index ] ) >>= sPrj; - // Make sure we don't double up with this project - if ( !sPrj.equals( sThisProject ) ) - sSearchList.push_back( sPrj ); - } + xPrjNameCache->getByName( sTemplateNames[ index ] ) >>= sPrj; + // Make sure we don't double up with this project + if ( !sPrj.equals( sThisProject ) ) + sSearchList.push_back( sPrj ); } - } - } - } - std::vector< rtl::OUString >::iterator it_end = sSearchList.end(); - for ( std::vector< rtl::OUString >::iterator it = sSearchList.begin(); it != it_end; ++it ) - { - bool bRes = hasMacro( pShell, *it, sModule, sProcedure ); - if ( bRes ) - { - aRes.SetResolved( true ); - aRes.SetMacroDocContext( pShell ); - sContainer = *it; - break; + } } } - aRes.SetResolvedMacro( sProcedure.Insert( '.', 0 ).Insert( sModule, 0).Insert( '.', 0 ).Insert( sContainer, 0 ) ); + std::vector< rtl::OUString >::iterator it_end = sSearchList.end(); + for ( std::vector< rtl::OUString >::iterator it = sSearchList.begin(); !aRes.mbFound && (it != it_end); ++it ) + { + aRes.mbFound = hasMacro( pShell, *it, sModule, sProcedure ); + if ( aRes.mbFound ) + sContainer = *it; + } + aRes.msResolvedMacro = sProcedure.Insert( '.', 0 ).Insert( sModule, 0).Insert( '.', 0 ).Insert( sContainer, 0 ); return aRes; } @@ -396,4 +394,116 @@ sal_Bool executeMacro( SfxObjectShell* pShell, const String& sMacroName, uno::Se } return bRes; } -} } // vba // ooo +// ============================================================================ + +uno::Sequence< ::rtl::OUString > VBAMacroResolver_getSupportedServiceNames() +{ + uno::Sequence< ::rtl::OUString > aServiceNames( 1 ); + aServiceNames[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.script.vba.VBAMacroResolver" ) ); + return aServiceNames; +} + +::rtl::OUString VBAMacroResolver_getImplementationName() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAMacroResolver" ) ); +} + +uno::Reference< uno::XInterface > SAL_CALL VBAMacroResolver_createInstance( const uno::Reference< lang::XMultiServiceFactory >& ) throw (uno::Exception) +{ + return static_cast< ::cppu::OWeakObject* >( new VBAMacroResolver ); +} + +// ============================================================================ + +VBAMacroResolver::VBAMacroResolver() : + mpObjShell( 0 ) +{ +} + +VBAMacroResolver::~VBAMacroResolver() +{ +} + +// com.sun.star.lang.XServiceInfo interface ----------------------------------- + +::rtl::OUString SAL_CALL VBAMacroResolver::getImplementationName() throw (uno::RuntimeException) +{ + return VBAMacroResolver_getImplementationName(); +} + +sal_Bool SAL_CALL VBAMacroResolver::supportsService( const ::rtl::OUString& rService ) throw (uno::RuntimeException) +{ + uno::Sequence< ::rtl::OUString > aServices = VBAMacroResolver_getSupportedServiceNames(); + const ::rtl::OUString* pArray = aServices.getConstArray(); + const ::rtl::OUString* pArrayEnd = pArray + aServices.getLength(); + return ::std::find( pArray, pArrayEnd, rService ) != pArrayEnd; +} + +uno::Sequence< ::rtl::OUString > SAL_CALL VBAMacroResolver::getSupportedServiceNames() throw (uno::RuntimeException) +{ + return VBAMacroResolver_getSupportedServiceNames(); +} + +// com.sun.star.lang.XInitialization interface -------------------------------- + +void SAL_CALL VBAMacroResolver::initialize( const uno::Sequence< uno::Any >& rArgs ) throw (uno::Exception, uno::RuntimeException) +{ + OSL_ENSURE( rArgs.getLength() < 2, "VBAMacroResolver::initialize - missing arguments" ); + if( rArgs.getLength() < 2 ) + throw uno::RuntimeException(); + + // first argument: document model + mxModel.set( rArgs[ 0 ], uno::UNO_QUERY_THROW ); + uno::Reference< lang::XUnoTunnel > xUnoTunnel( mxModel, uno::UNO_QUERY_THROW ); + mpObjShell = reinterpret_cast< SfxObjectShell* >( xUnoTunnel->getSomething( SfxObjectShell::getUnoTunnelId() ) ); + if( !mpObjShell ) + throw uno::RuntimeException(); + + // second argument: VBA project name + if( !(rArgs[ 1 ] >>= maProjectName) || (maProjectName.getLength() == 0) ) + throw uno::RuntimeException(); +} + +// com.sun.star.script.vba.XVBAMacroResolver interface ------------------------ + +::rtl::OUString SAL_CALL VBAMacroResolver::resolveVBAMacroToScriptURL( const ::rtl::OUString& rVBAMacroName ) throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + if( !mpObjShell ) + throw uno::RuntimeException(); + + // the name may be enclosed in apostrophs + ::rtl::OUString aMacroName = trimMacroName( rVBAMacroName ); + if( aMacroName.getLength() == 0 ) + throw lang::IllegalArgumentException(); + + // external references not supported here (syntax is "url!macroname" or "[url]!macroname" or "[url]macroname") + if( (aMacroName[ 0 ] == '[') || (aMacroName.indexOf( '!' ) >= 0) ) + throw lang::IllegalArgumentException(); + + // check if macro name starts with project name, replace with "Standard" + // TODO: adjust this when custom VBA project name is supported + sal_Int32 nDotPos = aMacroName.indexOf( '.' ); + if( (nDotPos == 0) || (nDotPos + 1 == aMacroName.getLength()) ) + throw lang::IllegalArgumentException(); + if( (nDotPos > 0) && aMacroName.matchIgnoreAsciiCase( maProjectName ) ) + aMacroName = aMacroName.copy( nDotPos + 1 ); + + // try to find the macro + MacroResolvedInfo aInfo = resolveVBAMacro( mpObjShell, aMacroName, false ); + if( !aInfo.mbFound ) + throw lang::IllegalArgumentException(); + + // build and return the script URL + return makeMacroURL( aInfo.msResolvedMacro ); +} + +::rtl::OUString SAL_CALL VBAMacroResolver::resolveScriptURLtoVBAMacro( const ::rtl::OUString& /*rScriptURL*/ ) throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + OSL_ENSURE( false, "VBAMacroResolver::resolveScriptURLtoVBAMacro - not implemented" ); + throw uno::RuntimeException(); +} + +// ============================================================================ + +} // namespace vba +} // namespace ooo diff --git a/filter/source/msfilter/services.cxx b/filter/source/msfilter/services.cxx new file mode 100755 index 000000000000..e34862ca0d13 --- /dev/null +++ b/filter/source/msfilter/services.cxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <cppuhelper/factory.hxx> +#include <string.h> + +using ::rtl::OUString; +using namespace ::com::sun::star; + +// ============================================================================ + +/* Steps to add an implementation 'MyClass' as a service: + + Step 1: Implement the static functions MyClass_getSupportedServiceNames(), + MyClass_getImplementationName(), and MyClass_createInstance() in the cxx + file of MyClass (see other examples in this module). + + Step 2: Add the line 'DECL_STATIC_FUNCS_???( MyClass )' below in this file. + If the service will be instanciated without component context, use + DECL_STATIC_FUNCS_FACTORY. If the service will be instanciated with + component context, use DECL_STATIC_FUNCS_COMPCONTEXT. + + Step 3: Add 'WRITE_SERVICE_INFO( MyClass )' in function + component_writeInfo() below in this file. + + Step 4: Add 'IMPLEMENT_SINGLEFACTORY( MyClass )' (instanciation without + component context) or 'IMPLEMENT_SINGLECOMPFACTORY( MyClass )' + (instanciation with component context) in function component_getFactory() + below in this file. + */ + +// ============================================================================ + +// Declare static functions providing service information --------------------- + +#define DECL_STATIC_FUNCS_FACTORY( className ) \ +extern OUString SAL_CALL className##_getImplementationName() throw(); \ +extern uno::Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw(); \ +extern uno::Reference< uno::XInterface > SAL_CALL className##_createInstance( \ + const uno::Reference< lang::XMultiServiceFactory >& rxFactory ) throw (uno::Exception) + +#define DECL_STATIC_FUNCS_COMPCONTEXT( className ) \ +extern OUString SAL_CALL className##_getImplementationName() throw(); \ +extern uno::Sequence< OUString > SAL_CALL className##_getSupportedServiceNames() throw(); \ +extern uno::Reference< uno::XInterface > SAL_CALL className##_createInstance( \ + const uno::Reference< uno::XComponentContext >& rxContext ) throw (uno::Exception) + +// step 2: add new classes in this list +namespace ooo { namespace vba { DECL_STATIC_FUNCS_FACTORY( VBAMacroResolver ); } } + +#undef DECL_STATIC_FUNCS_FACTORY +#undef DECL_STATIC_FUNCS_COMPCONTEXT + +// ---------------------------------------------------------------------------- + +extern "C" { + +// ---------------------------------------------------------------------------- + +SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment( const sal_Char **ppEnvironmentTypeName, uno_Environment ** /*ppEnvironment*/ ) +{ + *ppEnvironmentTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +// Write service information to registry -------------------------------------- + +void SAL_CALL writeInfo( registry::XRegistryKey* pRegistryKey, const OUString& rImplementationName, const uno::Sequence< OUString >& rServices ) +{ + uno::Reference< registry::XRegistryKey > xNewKey( pRegistryKey->createKey( + OUString( sal_Unicode( '/' ) ) + rImplementationName + OUString(RTL_CONSTASCII_USTRINGPARAM( "/UNO/SERVICES" ) ) ) ); + for( sal_Int32 i = 0; i < rServices.getLength(); ++i ) + xNewKey->createKey( rServices[i] ); +} + +#define WRITE_SERVICE_INFO( className ) \ + writeInfo( pKey, className##_getImplementationName(), className##_getSupportedServiceNames() ) + +SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pRegistryKey ) +{ + if( pRegistryKey ) try + { + registry::XRegistryKey* pKey = reinterpret_cast< registry::XRegistryKey* >( pRegistryKey ); + + // step 3: add new classes in this list + WRITE_SERVICE_INFO( ::ooo::vba::VBAMacroResolver ); + } + catch( registry::InvalidRegistryException& ) + { + OSL_ENSURE( sal_False, "so_vba - component_writeInfo - InvalidRegistryException" ); + } + return sal_True; +} + +#undef WRITE_SERVICE_INFO + +// Create a factory for the service instances --------------------------------- + +#define IMPLEMENT_SINGLEFACTORY( className ) \ +if( !bFound && className##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) ) \ +{ \ + xFactory = ::cppu::createSingleFactory( xMSF, className##_getImplementationName(), \ + className##_createInstance, className##_getSupportedServiceNames() ); \ + bFound = true; \ +} + +#define IMPLEMENT_SINGLECOMPFACTORY( className ) \ +if( !bFound && className##_getImplementationName().equalsAsciiL( pImplName, nImplNameLen ) ) \ +{ \ + xCompFactory = ::cppu::createSingleComponentFactory( className##_createInstance, \ + className##_getImplementationName(), className##_getSupportedServiceNames() ); \ + bFound = true; \ +} + +SAL_DLLPUBLIC_EXPORT void* SAL_CALL component_getFactory( const sal_Char* pImplName, void* pServiceManager, void* /*pRegistryKey*/ ) +{ + void* pReturn = 0; + if( pImplName && pServiceManager ) + { + uno::Reference< lang::XMultiServiceFactory > xMSF( reinterpret_cast< lang::XMultiServiceFactory* >( pServiceManager ) ); + + // define variables which are used in the macros + uno::Reference< lang::XSingleServiceFactory > xFactory; + uno::Reference< lang::XSingleComponentFactory > xCompFactory; + const sal_Int32 nImplNameLen = strlen( pImplName ); + bool bFound = false; + + // Step 4: add new class in this list + IMPLEMENT_SINGLEFACTORY( ::ooo::vba::VBAMacroResolver ) + + // factory is valid -> service was found + if( xFactory.is()) + { + xFactory->acquire(); + pReturn = xFactory.get(); + } + else if( xCompFactory.is() ) + { + xCompFactory->acquire(); + pReturn = xCompFactory.get(); + } + } + return pReturn; +} + +#undef IMPLEMENT_SINGLEFACTORY +#undef IMPLEMENT_SINGLECOMPFACTORY + +// ---------------------------------------------------------------------------- + +} // extern "C" + +// ============================================================================ diff --git a/oox/inc/oox/core/binarycodec.hxx b/oox/inc/oox/core/binarycodec.hxx index 8abafffa2481..1e9dba07c388 100644 --- a/oox/inc/oox/core/binarycodec.hxx +++ b/oox/inc/oox/core/binarycodec.hxx @@ -289,4 +289,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/core/binaryfilterbase.hxx b/oox/inc/oox/core/binaryfilterbase.hxx index bf249cdfab9b..f1cc7b399bce 100644 --- a/oox/inc/oox/core/binaryfilterbase.hxx +++ b/oox/inc/oox/core/binaryfilterbase.hxx @@ -59,4 +59,3 @@ typedef ::rtl::Reference< BinaryFilterBase > BinaryFilterRef; } // namespace oox #endif - diff --git a/oox/inc/oox/core/contexthandler.hxx b/oox/inc/oox/core/contexthandler.hxx index dd9ac686ff46..c5c198c34c23 100644 --- a/oox/inc/oox/core/contexthandler.hxx +++ b/oox/inc/oox/core/contexthandler.hxx @@ -29,9 +29,9 @@ #define OOX_CORE_CONTEXTHANDLER_HXX #include <boost/shared_ptr.hpp> -#include <rtl/ref.hxx> -#include <cppuhelper/implbase1.hxx> #include <com/sun/star/xml/sax/XFastContextHandler.hpp> +#include <cppuhelper/implbase1.hxx> +#include <rtl/ref.hxx> namespace com { namespace sun { namespace star { namespace xml { namespace sax { class XLocator; } } @@ -114,4 +114,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/core/contexthandler2.hxx b/oox/inc/oox/core/contexthandler2.hxx index 48f11c962e38..61c4ad9aa2da 100644 --- a/oox/inc/oox/core/contexthandler2.hxx +++ b/oox/inc/oox/core/contexthandler2.hxx @@ -41,28 +41,30 @@ namespace core { // ============================================================================ -struct ContextInfo; +struct ElementInfo; -/** Helper class that provides a context identifier stack. +/** Helper class that provides a context stack. Fragment handlers and context handlers derived from this helper class will - track the identifiers of the current context in a stack. The idea is to use - the same instance of a fragment handler or context handler to process + track the identifiers of the visited elements in a stack. The idea is to + use the same instance of a fragment handler or context handler to process several nested elements in an XML stream. For that, the abstract function - onCreateContext() has to return 'true' for the passed element. + onCreateContext() has to return 'this' for the passed element. Derived classes have to implement the createFastChildContext(), startFastElement(), characters(), and endFastElement() functions from the com.sun.star.xml.sax.XFastContextHandler interface by simply forwarding - them to the respective implCreateChildContext(), implStartCurrentContext(), - implCharacters(), and implEndCurrentContext() functions of this helper. The - new abstract functions have to be implemented according to the elements to - be processed. + them to the respective implCreateChildContext(), implStartElement(), + implCharacters(), and implEndElement() functions of this helper. This is + implemented already in the classes ContextHandler2 and FragmentHandler2. + The new abstract functions have to be implemented according to the elements + to be processed. Similarly, for binary import, derived classes have to forward the createRecordContext(), startRecord(), and endRecord() functions from the ContextHandler class to the implCreateRecordContext(), implStartRecord(), - and implEndRecord() functions of this helper. + and implEndRecord() functions of this helper. Again, this is implemented + already in the classes ContextHandler2 and FragmentHandler2. */ class ContextHandler2Helper { @@ -71,78 +73,97 @@ public: explicit ContextHandler2Helper( const ContextHandler2Helper& rParent ); virtual ~ContextHandler2Helper(); + // allow instances to be stored in ::rtl::Reference virtual void SAL_CALL acquire() throw() = 0; virtual void SAL_CALL release() throw() = 0; - virtual ContextHandler& queryContextHandler() = 0; - // interface -------------------------------------------------------------- - /** Will be called if a new context can be created for the passed element. + /** Will be called to create a context handler for the passed element. - Usually 'true' should be returned to improve performance by reusing the + Usually 'this' can be returned to improve performance by reusing the same instance to process several elements. Used by OOXML import only. */ virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) = 0; - /** Will be called if a new context element has been started. + /** Will be called when a new element has been started. + + This function is called at the context handler returned from + onCreateContext(), or, for root elements of an XML stream, at the + fragment handler itself. - The current element identifier can be accessed by using - getCurrentContext() or isCurrentContext(). Used by OOXML import only. + The current element identifier can be accessed with getCurrentElement() + or isCurrentElement(). Used by OOXML import only. */ virtual void onStartElement( const AttributeList& rAttribs ) = 0; - /** Will be called if the current context element is about to be left. + /** Will be called before a new child element starts, or if the current + element is about to be left. - The current element identifier can be accessed by using - getCurrentContext() or isCurrentContext(). Used by OOXML import only. + This helper function collects all text fragments received by the + characters() function (such as encoded characters which are passed in + separate calls to the characters() function), and passes the + concatenated and trimmed string. - @param rChars The characters collected in this element. + The current element identifier can be accessed with getCurrentElement() + or isCurrentElement(). Used by OOXML import only. */ - virtual void onEndElement( const ::rtl::OUString& rChars ) = 0; + virtual void onCharacters( const ::rtl::OUString& rChars ) = 0; - /** Will be called if a new context can be created for the passed element. + /** Will be called when the current element is about to be left. - Usually 'true' should be returned to improve performance by reusing the - same instance to process several elements. Used by OOBIN import only. + The current element identifier can be accessed with getCurrentElement() + or isCurrentElement(). Used by OOXML import only. + */ + virtual void onEndElement() = 0; + + /** Will be called to create a context handler for the passed record. + + Usually 'this' can be returned to improve performance by reusing the + same instance to process several records. Used by OOBIN import only. */ virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ) = 0; - /** Will be called if a new record in a binary stream has been started. + /** Will be called when a new record block in a binary stream has been + started. - The current record identifier can be accessed by using - getCurrentContext() or isCurrentContext(). Used by OOBIN import only. + The current record identifier can be accessed with getCurrentElement() + or isCurrentElement(). Used by OOBIN import only. */ virtual void onStartRecord( RecordInputStream& rStrm ) = 0; - /** Will be called if the current context record is about to be left. + /** Will be called when the current record block is about to be left. - The current record identifier can be accessed by using - getCurrentContext() or isCurrentContext(). Used by OOBIN import only. + The current record identifier can be accessed with getCurrentElement() + or isCurrentElement(). Used by OOBIN import only. */ virtual void onEndRecord() = 0; // helpers ---------------------------------------------------------------- - /** Returns the element identifier of the current topmost context. */ + /** Returns the identifier of the currently processed element. */ sal_Int32 getCurrentElement() const; - /** Returns true, if nElement contains the current topmost context. */ + /** Returns true, if nElement contains the identifier of the currently + processed element. */ inline bool isCurrentElement( sal_Int32 nElement ) const { return getCurrentElement() == nElement; } - /** Returns true, if either nElement1 or nElement2 contain the current topmost context. */ + /** Returns true, if either nElement1 or nElement2 contain the identifier + of the currently processed element. */ inline bool isCurrentElement( sal_Int32 nElement1, sal_Int32 nElement2 ) const { return isCurrentElement( nElement1 ) || isCurrentElement( nElement2 ); } - /** Returns the element identifier of the specified parent context. */ - sal_Int32 getPreviousElement( sal_Int32 nCountBack = 1 ) const; + /** Returns the identifier of the specified parent element. */ + sal_Int32 getParentElement( sal_Int32 nCountBack = 1 ) const; - /** Returns the element identifier of the specified parent context. */ - inline sal_Int32 isPreviousElement( sal_Int32 nElement, sal_Int32 nCountBack = 1 ) const - { return getPreviousElement( nCountBack ) == nElement; } + /** Returns true, if nElement contains the identifier of the specified + parent element. */ + inline sal_Int32 isParentElement( sal_Int32 nElement, sal_Int32 nCountBack = 1 ) const + { return getParentElement( nCountBack ) == nElement; } - /** Returns true, if the current element is the root element. */ + /** Returns true, if the element currently processed is the root element of + the context or fragment handler. */ bool isRootElement() const; // implementation --------------------------------------------------------- @@ -155,7 +176,7 @@ protected: const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs ); /** Must be called from startFastElement() in derived classes. */ - void implStartCurrentContext( + void implStartElement( sal_Int32 nElement, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs ); @@ -163,7 +184,7 @@ protected: void implCharacters( const ::rtl::OUString& rChars ); /** Must be called from endFastElement() in derived classes. */ - void implEndCurrentContext( sal_Int32 nElement ); + void implEndElement( sal_Int32 nElement ); /** Must be called from createRecordContext() in derived classes. */ ContextHandlerRef implCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); @@ -177,15 +198,15 @@ protected: private: ContextHandler2Helper& operator=( const ContextHandler2Helper& ); - ContextInfo& pushContextInfo( sal_Int32 nElement ); - void popContextInfo(); - void appendCollectedChars(); + ElementInfo& pushElementInfo( sal_Int32 nElement ); + void popElementInfo(); + void processCollectedChars(); private: - typedef ::std::vector< ContextInfo > ContextStack; + typedef ::std::vector< ElementInfo > ContextStack; typedef ::boost::shared_ptr< ContextStack > ContextStackRef; - ContextStackRef mxContextStack; /// Stack of processed contexts. + ContextStackRef mxContextStack; /// Stack of all processed elements. size_t mnRootStackSize; /// Stack size on construction time. bool mbEnableTrimSpace; /// True = trim whitespace in characters(). }; @@ -202,8 +223,6 @@ public: virtual void SAL_CALL acquire() throw() { ContextHandler::acquire(); } virtual void SAL_CALL release() throw() { ContextHandler::release(); } - virtual ContextHandler& queryContextHandler(); - // com.sun.star.xml.sax.XFastContextHandler interface --------------------- virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL @@ -237,7 +256,8 @@ public: virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); virtual void onStartElement( const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); virtual void onStartRecord( RecordInputStream& rStrm ); @@ -250,4 +270,3 @@ public: } // namespace oox #endif - diff --git a/oox/inc/oox/core/fasttokenhandler.hxx b/oox/inc/oox/core/fasttokenhandler.hxx index 84baccabdc67..01422aebc3ea 100644 --- a/oox/inc/oox/core/fasttokenhandler.hxx +++ b/oox/inc/oox/core/fasttokenhandler.hxx @@ -62,4 +62,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/core/filterbase.hxx b/oox/inc/oox/core/filterbase.hxx index 1757b2be4334..0371768d02a7 100644 --- a/oox/inc/oox/core/filterbase.hxx +++ b/oox/inc/oox/core/filterbase.hxx @@ -29,14 +29,14 @@ #define OOX_CORE_FILTERBASE_HXX #include <memory> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/document/XImporter.hpp> #include <com/sun/star/document/XExporter.hpp> #include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> #include <com/sun/star/io/XInputStream.hpp> #include <com/sun/star/io/XOutputStream.hpp> #include <com/sun/star/io/XStream.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> #include <cppuhelper/basemutex.hxx> #include <cppuhelper/implbase5.hxx> #include "oox/helper/binarystreambase.hxx" @@ -44,16 +44,16 @@ #include "oox/dllapi.h" namespace com { namespace sun { namespace star { - namespace lang { class XMultiServiceFactory; } namespace awt { struct DeviceInfo; } - namespace frame { class XModel; } - namespace task { class XStatusIndicator; } - namespace task { class XInteractionHandler; } namespace frame { class XFrame; } + namespace frame { class XModel; } + namespace graphic { class XGraphic; } namespace io { class XInputStream; } namespace io { class XOutputStream; } namespace io { class XStream; } - namespace graphic { class XGraphic; } + namespace lang { class XMultiServiceFactory; } + namespace task { class XInteractionHandler; } + namespace task { class XStatusIndicator; } } } } namespace comphelper { @@ -68,6 +68,7 @@ namespace oox { namespace oox { namespace ole { class OleObjectHelper; + class VbaProject; } } namespace oox { @@ -194,6 +195,9 @@ public: /** Returns a helper for the handling of OLE obejcts. */ ::oox::ole::OleObjectHelper& getOleObjectHelper() const; + /** Returns the VBA project manager. */ + ::oox::ole::VbaProject& getVbaProject() const; + /** Requests a password from the media descriptor or from the user. On success, the password will be inserted into the media descriptor. */ ::rtl::OUString requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const; @@ -271,6 +275,9 @@ private: resolving palette colors. */ virtual GraphicHelper* implCreateGraphicHelper() const; + /** Derived classes create a VBA project manager object. */ + virtual ::oox::ole::VbaProject* implCreateVbaProject() const = 0; + virtual ::rtl::OUString implGetImplementationName() const = 0; virtual StorageRef implCreateStorage( @@ -288,4 +295,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/core/filterdetect.hxx b/oox/inc/oox/core/filterdetect.hxx index 76e46050c24a..70c35ff26076 100644 --- a/oox/inc/oox/core/filterdetect.hxx +++ b/oox/inc/oox/core/filterdetect.hxx @@ -163,4 +163,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/core/fragmenthandler.hxx b/oox/inc/oox/core/fragmenthandler.hxx index 26d2ac540a7a..ba3164a74da8 100644 --- a/oox/inc/oox/core/fragmenthandler.hxx +++ b/oox/inc/oox/core/fragmenthandler.hxx @@ -134,4 +134,3 @@ typedef ::rtl::Reference< FragmentHandler > FragmentHandlerRef; } // namespace oox #endif - diff --git a/oox/inc/oox/core/fragmenthandler2.hxx b/oox/inc/oox/core/fragmenthandler2.hxx index 9b864260b853..2473b9e91436 100644 --- a/oox/inc/oox/core/fragmenthandler2.hxx +++ b/oox/inc/oox/core/fragmenthandler2.hxx @@ -49,8 +49,6 @@ public: virtual void SAL_CALL acquire() throw() { FragmentHandler::acquire(); } virtual void SAL_CALL release() throw() { FragmentHandler::release(); } - virtual ContextHandler& queryContextHandler(); - // com.sun.star.xml.sax.XFastContextHandler interface --------------------- virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL @@ -94,7 +92,8 @@ public: virtual ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); virtual void onStartElement( const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); virtual ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); virtual void onStartRecord( RecordInputStream& rStrm ); @@ -112,4 +111,3 @@ public: } // namespace oox #endif - diff --git a/oox/inc/oox/core/recordparser.hxx b/oox/inc/oox/core/recordparser.hxx index e499195c52f8..4600be3ff832 100644 --- a/oox/inc/oox/core/recordparser.hxx +++ b/oox/inc/oox/core/recordparser.hxx @@ -29,7 +29,6 @@ #define OOX_CORE_RECORDPARSER_HXX #include <map> -#include <com/sun/star/uno/Reference.hxx> #include <com/sun/star/io/IOException.hpp> #include <com/sun/star/xml/sax/SAXException.hpp> #include <rtl/ref.hxx> @@ -95,4 +94,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/core/relations.hxx b/oox/inc/oox/core/relations.hxx index 4ca8ca3899e7..6abb48c361a0 100644 --- a/oox/inc/oox/core/relations.hxx +++ b/oox/inc/oox/core/relations.hxx @@ -35,6 +35,8 @@ namespace oox { namespace core { +// ============================================================================ + /** Expands to an OUString containing an officeDocument relation type created from the passed literal(!) ASCII(!) character array. */ #define CREATE_OFFICEDOC_RELATIONSTYPE( ascii ) \ @@ -99,4 +101,3 @@ private: } // namespace oox #endif // OOX_CORE_RELATIONS - diff --git a/oox/inc/oox/core/relationshandler.hxx b/oox/inc/oox/core/relationshandler.hxx index 3211888ecc9f..b2da8d59c39f 100644 --- a/oox/inc/oox/core/relationshandler.hxx +++ b/oox/inc/oox/core/relationshandler.hxx @@ -58,4 +58,3 @@ private: } // namespace oox #endif // OOX_CORE_RELATIONSHANDLER - diff --git a/oox/inc/oox/core/xmlfilterbase.hxx b/oox/inc/oox/core/xmlfilterbase.hxx index 30efeb0e9440..796cd82781c0 100644 --- a/oox/inc/oox/core/xmlfilterbase.hxx +++ b/oox/inc/oox/core/xmlfilterbase.hxx @@ -28,16 +28,16 @@ #ifndef OOX_CORE_XMLFILTERBASE_HXX #define OOX_CORE_XMLFILTERBASE_HXX +#include <com/sun/star/text/XText.hpp> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/text/XTextField.hpp> #include <rtl/ref.hxx> #include <rtl/string.hxx> #include <rtl/ustring.hxx> -#include "oox/drawingml/table/tablestylelist.hxx" #include "oox/core/filterbase.hxx" #include "oox/core/relations.hxx" -#include <oox/dllapi.h> -#include <com/sun/star/text/XTextField.hpp> -#include <com/sun/star/text/XTextCursor.hpp> -#include <com/sun/star/text/XText.hpp> +#include "oox/drawingml/table/tablestylelist.hxx" +#include "oox/dllapi.h" namespace com { namespace sun { namespace star { namespace container { class XNameContainer; } @@ -46,9 +46,11 @@ namespace com { namespace sun { namespace star { namespace xml { namespace sax { class XFastDocumentHandler; } } } } } -namespace oox { namespace drawingml { class Theme; } } -namespace oox { namespace drawingml { namespace chart { class ChartConverter; } } } -namespace oox { namespace vml { class Drawing; } } +namespace oox { + namespace drawingml { class Theme; } + namespace drawingml { namespace chart { class ChartConverter; } } + namespace vml { class Drawing; } +} namespace sax_fastparser { class FastSerializerHelper; @@ -61,6 +63,8 @@ namespace core { class FragmentHandler; +// ============================================================================ + struct TextField { com::sun::star::uno::Reference< com::sun::star::text::XText > xText; com::sun::star::uno::Reference< com::sun::star::text::XTextCursor > xTextCursor; @@ -222,4 +226,3 @@ typedef ::rtl::Reference< XmlFilterBase > XmlFilterRef; } // namespace oox #endif - diff --git a/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx b/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx index e43dc176c297..3ff545cda295 100644 --- a/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx +++ b/oox/inc/oox/drawingml/chart/chartdrawingfragment.hxx @@ -101,7 +101,8 @@ public: virtual ~ChartDrawingFragment(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); private: ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > diff --git a/oox/inc/oox/drawingml/chart/datasourcecontext.hxx b/oox/inc/oox/drawingml/chart/datasourcecontext.hxx index e5183e64caa4..1cffa32e382a 100644 --- a/oox/inc/oox/drawingml/chart/datasourcecontext.hxx +++ b/oox/inc/oox/drawingml/chart/datasourcecontext.hxx @@ -51,7 +51,7 @@ public: virtual ~DoubleSequenceContext(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); private: sal_Int32 mnPtIndex; /// Current data point index. @@ -69,7 +69,7 @@ public: virtual ~StringSequenceContext(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); private: sal_Int32 mnPtIndex; /// Current data point index. diff --git a/oox/inc/oox/drawingml/chart/seriescontext.hxx b/oox/inc/oox/drawingml/chart/seriescontext.hxx index 100e7755cdca..ef50bc94866c 100644 --- a/oox/inc/oox/drawingml/chart/seriescontext.hxx +++ b/oox/inc/oox/drawingml/chart/seriescontext.hxx @@ -47,7 +47,7 @@ public: virtual ~DataLabelContext(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); }; // ============================================================================ @@ -63,7 +63,7 @@ public: virtual ~DataLabelsContext(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); }; // ============================================================================ @@ -124,7 +124,7 @@ public: virtual ~TrendlineContext(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); }; // ============================================================================ diff --git a/oox/inc/oox/drawingml/chart/titlecontext.hxx b/oox/inc/oox/drawingml/chart/titlecontext.hxx index e3d274c1744b..45969bf150c2 100644 --- a/oox/inc/oox/drawingml/chart/titlecontext.hxx +++ b/oox/inc/oox/drawingml/chart/titlecontext.hxx @@ -47,7 +47,7 @@ public: virtual ~TextContext(); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); }; // ============================================================================ diff --git a/oox/inc/oox/drawingml/graphicshapecontext.hxx b/oox/inc/oox/drawingml/graphicshapecontext.hxx index d515a4553936..5f27efdf15e7 100644 --- a/oox/inc/oox/drawingml/graphicshapecontext.hxx +++ b/oox/inc/oox/drawingml/graphicshapecontext.hxx @@ -68,7 +68,7 @@ public: virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 Element, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& Attribs ) throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); private: - ::boost::shared_ptr< ::oox::vml::OleObjectInfo > mxOleObjectInfo; + ::oox::vml::OleObjectInfo& mrOleObjectInfo; }; // ==================================================================== @@ -106,7 +106,7 @@ public: throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); private: - bool mbEmbedShapes; + ChartShapeInfo& mrChartShapeInfo; }; // ==================================================================== diff --git a/oox/inc/oox/drawingml/shape.hxx b/oox/inc/oox/drawingml/shape.hxx index d6cab48f6bb5..2114f8d9cf02 100644 --- a/oox/inc/oox/drawingml/shape.hxx +++ b/oox/inc/oox/drawingml/shape.hxx @@ -40,6 +40,10 @@ #include <vector> #include <map> +namespace oox { namespace vml { + struct OleObjectInfo; +} } + namespace oox { namespace drawingml { class CustomShapeProperties; @@ -57,37 +61,15 @@ typedef ::std::map< sal_Int32, ShapeStyleRef > ShapeStyleRefMap; // ============================================================================ -/** A callback that will be called before and after the API shape is created - from the imported shape. - - An instance of a derived class of this callback can be set at every - ::oox::drawingml::Shape instance to implement anything that needs a created - and inserted XShape. - */ -class CreateShapeCallback +/** Additional information for a chart embedded in a drawing shape. */ +struct ChartShapeInfo { -public: - virtual ::rtl::OUString onCreateXShape( - const ::rtl::OUString& rServiceName, - const ::com::sun::star::awt::Rectangle& rShapeRect ); + ::rtl::OUString maFragmentPath; /// Path to related XML stream, e.g. for charts. + bool mbEmbedShapes; /// True = load chart shapes into chart, false = load into parent drawpage. - virtual void onXShapeCreated( - const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, - const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes ) const; - - inline const PropertyMap& getShapeProperties() const { return maShapeProps; } - -protected: - explicit CreateShapeCallback( ::oox::core::XmlFilterBase& rFilter ); - virtual ~CreateShapeCallback(); - -protected: - ::oox::core::XmlFilterBase& mrFilter; - PropertyMap maShapeProps; + inline explicit ChartShapeInfo( bool bEmbedShapes ) : mbEmbedShapes( bEmbedShapes ) {} }; -typedef ::boost::shared_ptr< CreateShapeCallback > CreateShapeCallbackRef; - // ============================================================================ class Shape @@ -95,7 +77,7 @@ class Shape { public: - Shape( const sal_Char* pServiceType = NULL ); + explicit Shape( const sal_Char* pServiceType = 0 ); virtual ~Shape(); rtl::OUString& getServiceName(){ return msServiceName; } @@ -136,6 +118,11 @@ public: // setDefaults has to be called if styles are imported (OfficeXML is not storing properties having the default value) void setDefaults(); + ::oox::vml::OleObjectInfo& setOleObjectType(); + ChartShapeInfo& setChartType( bool bEmbedShapes ); + void setDiagramType(); + void setTableType(); + void setTextBody(const TextBodyPtr & pTextBody); TextBodyPtr getTextBody(); void setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle ); @@ -145,11 +132,9 @@ public: inline const ShapeStyleRefMap& getShapeStyleRefs() const { return maShapeStyleRefs; } const ShapeStyleRef* getShapeStyleRef( sal_Int32 nRefType ) const; - inline void setCreateShapeCallback( CreateShapeCallbackRef xCallback ) { mxCreateCallback = xCallback; } - // addShape is creating and inserting the corresponding XShape. void addShape( - const oox::core::XmlFilterBase& rFilterBase, + ::oox::core::XmlFilterBase& rFilterBase, const Theme* pTheme, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ::com::sun::star::awt::Rectangle* pShapeRect = 0, @@ -166,7 +151,7 @@ protected: ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createAndInsert( - const ::oox::core::XmlFilterBase& rFilterBase, + ::oox::core::XmlFilterBase& rFilterBase, const ::rtl::OUString& rServiceName, const Theme* pTheme, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, @@ -174,13 +159,22 @@ protected: sal_Bool bClearText ); void addChildren( - const ::oox::core::XmlFilterBase& rFilterBase, + ::oox::core::XmlFilterBase& rFilterBase, Shape& rMaster, const Theme* pTheme, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, const ::com::sun::star::awt::Rectangle& rClientRect, ShapeIdMap* pShapeMap ); + virtual ::rtl::OUString finalizeServiceName( + ::oox::core::XmlFilterBase& rFilter, + const ::rtl::OUString& rServiceName, + const ::com::sun::star::awt::Rectangle& rShapeRect ); + + virtual void finalizeXShape( + ::oox::core::XmlFilterBase& rFilter, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes ); + std::vector< ShapePtr > maChildren; // only used for group shapes TextBodyPtr mpTextBody; LinePropertiesPtr mpLinePropertiesPtr; @@ -204,7 +198,22 @@ protected: com::sun::star::awt::Point maPosition; private: - CreateShapeCallbackRef mxCreateCallback; + enum FrameType + { + FRAMETYPE_GENERIC, /// Generic shape, no special type. + FRAMETYPE_OLEOBJECT, /// OLE object embedded in a shape. + FRAMETYPE_CHART, /// Chart embedded in a shape. + FRAMETYPE_DIAGRAM, /// Complex diagram drawing shape. + FRAMETYPE_TABLE /// A table embedded in a shape. + }; + + typedef ::boost::shared_ptr< ::oox::vml::OleObjectInfo > OleObjectInfoRef; + typedef ::boost::shared_ptr< ChartShapeInfo > ChartShapeInfoRef; + + FrameType meFrameType; /// Type for graphic frame shapes. + OleObjectInfoRef mxOleObjectInfo; /// Additional data for OLE objects. + ChartShapeInfoRef mxChartShapeInfo; /// Additional data for chart shapes. + sal_Int32 mnRotation; sal_Bool mbFlipH; sal_Bool mbFlipV; @@ -213,6 +222,8 @@ private: ::rtl::OUString GetShapeType( sal_Int32 nType ); +// ============================================================================ + } } #endif // OOX_DRAWINGML_SHAPE_HXX diff --git a/oox/inc/oox/helper/attributelist.hxx b/oox/inc/oox/helper/attributelist.hxx index ad746771cab8..f2919e889994 100644 --- a/oox/inc/oox/helper/attributelist.hxx +++ b/oox/inc/oox/helper/attributelist.hxx @@ -43,6 +43,9 @@ namespace oox { class AttributeConversion { public: + /** Returns the XML token identifier from the passed string. */ + static sal_Int32 decodeToken( const ::rtl::OUString& rValue ); + /** Returns the decoded string value. All characters in the format '_xHHHH_' (H being a hexadecimal digit), will be decoded. */ static ::rtl::OUString decodeXString( const ::rtl::OUString& rValue ); diff --git a/oox/inc/oox/ole/axbinaryreader.hxx b/oox/inc/oox/ole/axbinaryreader.hxx index e3f102716e17..9b3cfae723b8 100755 --- a/oox/inc/oox/ole/axbinaryreader.hxx +++ b/oox/inc/oox/ole/axbinaryreader.hxx @@ -92,6 +92,8 @@ typedef ::std::vector< ::rtl::OUString > AxStringArray; // ============================================================================ +const sal_Char* const AX_GUID_CFONT = "{AFC20920-DA4E-11CE-B943-00AA006887B4}"; + const sal_uInt32 AX_FONTDATA_BOLD = 0x00000001; const sal_uInt32 AX_FONTDATA_ITALIC = 0x00000002; const sal_uInt32 AX_FONTDATA_UNDERLINE = 0x00000004; @@ -111,6 +113,7 @@ struct AxFontData sal_Int32 mnFontHeight; /// Height of the font (not really twips, see code). sal_Int32 mnFontCharSet; /// Windows character set of the font. sal_Int32 mnHorAlign; /// Horizontal text alignment. + bool mbDblUnderline; /// True = double underline style (legacy VML drawing controls only). explicit AxFontData(); diff --git a/oox/inc/oox/ole/axcontrol.hxx b/oox/inc/oox/ole/axcontrol.hxx index 8638a4869d72..8bc9cd622b2b 100644 --- a/oox/inc/oox/ole/axcontrol.hxx +++ b/oox/inc/oox/ole/axcontrol.hxx @@ -58,6 +58,9 @@ const sal_Char* const COMCTL_GUID_SCROLLBAR_60 = "{FE38753A-44A3-11D1-B5B7- const sal_Char* const COMCTL_GUID_PROGRESSBAR_50 = "{0713E8D2-850A-101B-AFC0-4210102A8DA7}"; const sal_Char* const COMCTL_GUID_PROGRESSBAR_60 = "{35053A22-8589-11D1-B16A-00C0F0283628}"; +const sal_uInt16 COMCTL_VERSION_50 = 5; +const sal_uInt16 COMCTL_VERSION_60 = 6; + // ---------------------------------------------------------------------------- const sal_Char* const AX_GUID_COMMANDBUTTON = "{D7053240-CE69-11CD-A777-00DD01143C57}"; @@ -79,6 +82,28 @@ const sal_uInt32 AX_SYSCOLOR_WINDOWTEXT = 0x80000008; const sal_uInt32 AX_SYSCOLOR_BUTTONFACE = 0x8000000F; const sal_uInt32 AX_SYSCOLOR_BUTTONTEXT = 0x80000012; +const sal_uInt32 AX_FLAGS_ENABLED = 0x00000002; +const sal_uInt32 AX_FLAGS_LOCKED = 0x00000004; +const sal_uInt32 AX_FLAGS_OPAQUE = 0x00000008; +const sal_uInt32 AX_FLAGS_COLUMNHEADS = 0x00000400; +const sal_uInt32 AX_FLAGS_ENTIREROWS = 0x00000800; +const sal_uInt32 AX_FLAGS_EXISTINGENTRIES = 0x00001000; +const sal_uInt32 AX_FLAGS_CAPTIONLEFT = 0x00002000; +const sal_uInt32 AX_FLAGS_EDITABLE = 0x00004000; +const sal_uInt32 AX_FLAGS_IMEMODE_MASK = 0x00078000; +const sal_uInt32 AX_FLAGS_DRAGENABLED = 0x00080000; +const sal_uInt32 AX_FLAGS_ENTERASNEWLINE = 0x00100000; +const sal_uInt32 AX_FLAGS_KEEPSELECTION = 0x00200000; +const sal_uInt32 AX_FLAGS_TABASCHARACTER = 0x00400000; +const sal_uInt32 AX_FLAGS_WORDWRAP = 0x00800000; +const sal_uInt32 AX_FLAGS_BORDERSSUPPRESSED = 0x02000000; +const sal_uInt32 AX_FLAGS_SELECTLINE = 0x04000000; +const sal_uInt32 AX_FLAGS_SINGLECHARSELECT = 0x08000000; +const sal_uInt32 AX_FLAGS_AUTOSIZE = 0x10000000; +const sal_uInt32 AX_FLAGS_HIDESELECTION = 0x20000000; +const sal_uInt32 AX_FLAGS_MAXLENAUTOTAB = 0x40000000; +const sal_uInt32 AX_FLAGS_MULTILINE = 0x80000000; + const sal_Int32 AX_BORDERSTYLE_NONE = 0; const sal_Int32 AX_BORDERSTYLE_SINGLE = 1; @@ -98,6 +123,26 @@ const sal_Int32 AX_PICALIGN_CENTER = 2; const sal_Int32 AX_PICALIGN_BOTTOMLEFT = 3; const sal_Int32 AX_PICALIGN_BOTTOMRIGHT = 4; +const sal_Int32 AX_DISPLAYSTYLE_TEXT = 1; +const sal_Int32 AX_DISPLAYSTYLE_LISTBOX = 2; +const sal_Int32 AX_DISPLAYSTYLE_COMBOBOX = 3; +const sal_Int32 AX_DISPLAYSTYLE_CHECKBOX = 4; +const sal_Int32 AX_DISPLAYSTYLE_OPTBUTTON = 5; +const sal_Int32 AX_DISPLAYSTYLE_TOGGLE = 6; +const sal_Int32 AX_DISPLAYSTYLE_DROPDOWN = 7; + +const sal_Int32 AX_SELCTION_SINGLE = 0; +const sal_Int32 AX_SELCTION_MULTI = 1; +const sal_Int32 AX_SELCTION_EXTENDED = 2; + +const sal_Int32 AX_SHOWDROPBUTTON_NEVER = 0; +const sal_Int32 AX_SHOWDROPBUTTON_FOCUS = 1; +const sal_Int32 AX_SHOWDROPBUTTON_ALWAYS = 2; + +const sal_Int32 AX_SCROLLBAR_NONE = 0x00; +const sal_Int32 AX_SCROLLBAR_HORIZONTAL = 0x01; +const sal_Int32 AX_SCROLLBAR_VERTICAL = 0x02; + // ---------------------------------------------------------------------------- /** Enumerates all UNO API control types supported by these filters. */ @@ -109,6 +154,7 @@ enum ApiControlType API_CONTROL_CHECKBOX, API_CONTROL_RADIOBUTTON, API_CONTROL_EDIT, + API_CONTROL_NUMERIC, API_CONTROL_LISTBOX, API_CONTROL_COMBOBOX, API_CONTROL_SPINBUTTON, @@ -182,6 +228,11 @@ public: PropertyMap& rPropMap, bool bHorizontal ) const; + /** Converts the vertical alignment to UNO properties. */ + void convertVerticalAlign( + PropertyMap& rPropMap, + sal_Int32 nVerticalAlign ) const; + /** Converts common scrollbar settings to UNO properties. */ void convertScrollBar( PropertyMap& rPropMap, @@ -289,8 +340,10 @@ public: /** Converts the control size to UNO properties. */ void convertSize( PropertyMap& rPropMap, const ControlConverter& rConv ) const; -protected: +public: // direct access needed for legacy VML drawing controls AxPairData maSize; /// Size of the control in 1/100 mm. + +protected: bool mbAwtModel; /// True = AWT control model, false = form component. }; @@ -410,8 +463,10 @@ public: /** Returns the font height in points. */ inline sal_Int16 getFontHeight() const { return maFontData.getHeightPoints(); } -protected: +public: // direct access needed for legacy VML drawing controls AxFontData maFontData; /// The font settings. + +private: bool mbSupportsAlign; /// True = UNO model supports Align property. }; @@ -430,13 +485,14 @@ public: virtual ApiControlType getControlType() const; virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const; -private: +public: // direct access needed for legacy VML drawing controls StreamDataSequence maPictureData; /// Binary picture stream. ::rtl::OUString maCaption; /// Visible caption of the button. sal_uInt32 mnTextColor; /// Text color. sal_uInt32 mnBackColor; /// Fill color. sal_uInt32 mnFlags; /// Various flags. sal_uInt32 mnPicturePos; /// Position of the picture relative to text. + sal_Int32 mnVerticalAlign; /// Vertical alignment (legacy VML drawing controls only). bool mbFocusOnClick; /// True = take focus on click. }; @@ -454,7 +510,7 @@ public: virtual ApiControlType getControlType() const; virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const; -private: +public: // direct access needed for legacy VML drawing controls ::rtl::OUString maCaption; /// Visible caption of the button. sal_uInt32 mnTextColor; /// Text color. sal_uInt32 mnBackColor; /// Fill color. @@ -462,6 +518,7 @@ private: sal_uInt32 mnBorderColor; /// Flat border color. sal_Int32 mnBorderStyle; /// Flat border style. sal_Int32 mnSpecialEffect; /// 3D border effect. + sal_Int32 mnVerticalAlign; /// Vertical alignment (legacy VML drawing controls only). }; // ============================================================================ @@ -504,7 +561,7 @@ public: virtual bool importBinaryModel( BinaryInputStream& rInStrm ); virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const; -protected: +public: // direct access needed for legacy VML drawing controls StreamDataSequence maPictureData; /// Binary picture stream. ::rtl::OUString maCaption; /// Visible caption of the button. ::rtl::OUString maValue; /// Current value of the control. @@ -524,6 +581,7 @@ protected: sal_Int32 mnMaxLength; /// Maximum character count. sal_Int32 mnPasswordChar; /// Password character in edit fields. sal_Int32 mnListRows; /// Number of rows in dropdown box. + sal_Int32 mnVerticalAlign; /// Vertical alignment (legacy VML drawing controls only). }; // ============================================================================ @@ -579,6 +637,18 @@ public: // ============================================================================ +/** Model for a numeric field (legacy drawing controls only). */ +class AxNumericFieldModel : public AxMorphDataModelBase +{ +public: + explicit AxNumericFieldModel(); + + virtual ApiControlType getControlType() const; + virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const; +}; + +// ============================================================================ + /** Model for a Forms 2.0 list box. */ class AxListBoxModel : public AxMorphDataModelBase { @@ -615,7 +685,7 @@ public: virtual ApiControlType getControlType() const; virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const; -private: +public: // direct access needed for legacy VML drawing controls sal_uInt32 mnArrowColor; /// Button arrow color. sal_uInt32 mnBackColor; /// Fill color. sal_uInt32 mnFlags; /// Various flags. @@ -641,7 +711,7 @@ public: virtual ApiControlType getControlType() const; virtual void convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const; -private: +public: // direct access needed for legacy VML drawing controls sal_uInt32 mnArrowColor; /// Button arrow color. sal_uInt32 mnBackColor; /// Fill color. sal_uInt32 mnFlags; /// Various flags. @@ -705,7 +775,7 @@ public: model from the 'f' stream. */ bool importClassTable( BinaryInputStream& rInStrm, AxClassTable& orClassTable ); -protected: +public: // direct access needed for legacy VML drawing controls StreamDataSequence maPictureData; /// Binary picture stream. ::rtl::OUString maCaption; /// Visible caption of the form. AxPairData maLogicalSize; /// Logical form size (scroll area). @@ -790,14 +860,27 @@ class EmbeddedControl { public: explicit EmbeddedControl( const ::rtl::OUString& rName ); - ~EmbeddedControl(); + virtual ~EmbeddedControl(); + + /** Creates and returns the internal control model of the specified type. */ + template< typename ModelType > + inline ModelType& createModel(); + + /** Creates and returns the internal control model of the specified type. */ + template< typename ModelType, typename ParamType > + inline ModelType& createModel( const ParamType& rParam ); /** Creates and returns the internal control model according to the passed MS class identifier. */ - ControlModelRef createModel( const ::rtl::OUString& rClassId ); + ControlModelBase* createModelFromGuid( const ::rtl::OUString& rClassId ); /** Returns true, if the internal control model exists. */ inline bool hasModel() const { return mxModel.get() != 0; } + /** Returns read-only access to the internal control model. */ + inline const ControlModelBase* getModel() const { return mxModel.get(); } + /** Returns read/write access to the internal control model. */ + inline ControlModelBase* getModel() { return mxModel.get(); } + /** Returns the UNO service name needed to construct the control model. */ ::rtl::OUString getServiceName() const; @@ -811,10 +894,30 @@ private: ::rtl::OUString maName; /// Name of the control. }; +// ---------------------------------------------------------------------------- + +template< typename ModelType > +inline ModelType& EmbeddedControl::createModel() +{ + ::boost::shared_ptr< ModelType > xModel( new ModelType ); + mxModel = xModel; + xModel->setFormComponentMode(); + return *xModel; +} + +template< typename ModelType, typename ParamType > +inline ModelType& EmbeddedControl::createModel( const ParamType& rParam ) +{ + ::boost::shared_ptr< ModelType > xModel( new ModelType( rParam ) ); + mxModel = xModel; + xModel->setFormComponentMode(); + return *xModel; +} + // ============================================================================ /** A wrapper for a control form embedded directly in a draw page. */ -class EmbeddedForm : public ControlConverter +class EmbeddedForm { public: explicit EmbeddedForm( @@ -823,20 +926,22 @@ public: const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr = true ); - /** Converts the passed ActiveX control and inserts it into the form. + /** Converts the passed control and inserts the control model into the form. @return The API control model, if conversion was successful. */ ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > - convertAndInsert( const EmbeddedControl& rControl ); + convertAndInsert( const EmbeddedControl& rControl, sal_Int32& rnCtrlIndex ); -private: - /** Tries to insert the passed control model into the form. */ - bool insertControl( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxCtrlModel ); + /** Returns the XIndexContainer interface of the UNO control form, if existing. */ + inline ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > + getXForm() const { return mxFormIC; } +private: /** Creates the form that will hold the form controls. */ ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > - createForm(); + createXForm(); private: + ControlConverter maControlConv; ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxModelFactory; ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormsSupplier > mxFormsSupp; ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > mxFormIC; diff --git a/oox/inc/oox/ole/olehelper.hxx b/oox/inc/oox/ole/olehelper.hxx index ba46d3baf6df..f19efa835f4e 100644 --- a/oox/inc/oox/ole/olehelper.hxx +++ b/oox/inc/oox/ole/olehelper.hxx @@ -100,6 +100,10 @@ public: sal_uInt32 nOleColor, bool bDefaultColorBgr = true ); + /** Returns the OLE color from the passed UNO RGB color. + */ + static sal_uInt32 encodeOleColor( sal_Int32 nRgbColor ); + /** Imports a GUID from the passed binary stream and returns its string representation (in uppercase characters). */ diff --git a/oox/inc/oox/ole/vbahelper.hxx b/oox/inc/oox/ole/vbahelper.hxx index 76dc1c736025..a62a6bd06765 100755 --- a/oox/inc/oox/ole/vbahelper.hxx +++ b/oox/inc/oox/ole/vbahelper.hxx @@ -59,6 +59,7 @@ const sal_uInt16 VBA_ID_MODULETYPEPROCEDURAL = 0x0021; const sal_uInt16 VBA_ID_PROJECTCODEPAGE = 0x0003; const sal_uInt16 VBA_ID_PROJECTEND = 0x0010; const sal_uInt16 VBA_ID_PROJECTMODULES = 0x000F; +const sal_uInt16 VBA_ID_PROJECTNAME = 0x0004; const sal_uInt16 VBA_ID_PROJECTVERSION = 0x0009; // ============================================================================ diff --git a/oox/inc/oox/ole/vbaproject.hxx b/oox/inc/oox/ole/vbaproject.hxx index cb4562a2b7c5..6834fa08f252 100755 --- a/oox/inc/oox/ole/vbaproject.hxx +++ b/oox/inc/oox/ole/vbaproject.hxx @@ -37,8 +37,9 @@ namespace com { namespace sun { namespace star { namespace container { class XNameContainer; } namespace document { class XEventsSupplier; } namespace frame { class XModel; } - namespace script { class XLibraryContainer; } namespace lang { class XMultiServiceFactory; } + namespace script { class XLibraryContainer; } + namespace script { namespace vba { class XVBAMacroResolver; } } } } } namespace oox { class GraphicHelper; } @@ -70,6 +71,47 @@ private: // ============================================================================ +/** Base class for objects that attach a amcro to a specific action. + + Purpose is to collect objects that need to attach a VBA macro to an action. + The VBA project will be loaded at a very late point of the document import + process, because it depends on an initialized core document model (e.g. + spreadsheet codenames). Some objects that want to attach a VBA macro to an + action (e.g. mouse click action for drawing shapes) are loaded long before + the VBA project. The drawback is that in most cases macros are specified + without module name, or the VBA project name is part of the macro name. + In the former case, all code modules have to be scanned for the macro to be + able to create a valid script URL. + + The import code will register these requests to attach a VBA macro with an + instance of a class derived from this base class. The derived class will + store all information needed to finally attach the macro to the action, + once the VBA project has been imported. + */ +class VbaMacroAttacherBase +{ +public: + explicit VbaMacroAttacherBase( const ::rtl::OUString& rMacroName ); + virtual ~VbaMacroAttacherBase(); + + /** Resolves the internal macro name to the related macro URL, and attaches + the macro to the object. */ + void resolveAndAttachMacro( + const ::com::sun::star::uno::Reference< ::com::sun::star::script::vba::XVBAMacroResolver >& rxResolver ); + +private: + /** Called after the VBA project has been imported. Derived classes will + attach the passed script to the object represented by this instance. */ + virtual void attachMacro( const ::rtl::OUString& rScriptUrl ) = 0; + +private: + ::rtl::OUString maMacroName; +}; + +typedef ::boost::shared_ptr< VbaMacroAttacherBase > VbaMacroAttacherRef; + +// ============================================================================ + class OOX_DLLPUBLIC VbaProject : public VbaFilterConfig { public: @@ -88,6 +130,10 @@ public: const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr = true ); + /** Registers a macro atatcher object. For details, see description of the + VbaMacroAttacherBase class. */ + void registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher ); + /** Returns true, if the document contains at least one code module. */ bool hasModules() const; /** Returns true, if the document contains the specified code module. */ @@ -254,8 +300,10 @@ protected: imported. */ void addDummyModule( const ::rtl::OUString& rName, sal_Int32 nType ); - /** Called when the import process of the VBA code modules starts. */ - virtual void prepareModuleImport(); + /** Called when the import process of the VBA project has been started. */ + virtual void prepareImport(); + /** Called when the import process of the VBA project is finished. */ + virtual void finalizeImport(); private: VbaProject( const VbaProject& ); @@ -280,11 +328,15 @@ private: const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ); + /** Attaches VBA macros to objects registered via registerMacroAttacher(). */ + void attachMacros(); + /** Copies the entire VBA project storage to the passed document model. */ void copyStorage( StorageBase& rVbaPrjStrg ); private: - typedef ::std::map< ::rtl::OUString, sal_Int32 > DummyModuleMap; + typedef RefVector< VbaMacroAttacherBase > MacroAttacherVector; + typedef ::std::map< ::rtl::OUString, sal_Int32 > DummyModuleMap; ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxGlobalFactory; /// Global service factory. @@ -294,8 +346,9 @@ private: mxBasicLib; /// The Basic library of the document used for import. ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer > mxDialogLib; /// The dialog library of the document used for import. + MacroAttacherVector maMacroAttachers; /// Objects that want to attach a VBA macro to an action. DummyModuleMap maDummyModules; /// Additional empty modules created on import. - const ::rtl::OUString maLibName; /// Name for Basic and dialog library used for import. + ::rtl::OUString maPrjName; /// Name of the VBA project. }; // ============================================================================ diff --git a/oox/inc/oox/ppt/pptimport.hxx b/oox/inc/oox/ppt/pptimport.hxx index c4ee29447c64..cb87d07329e3 100644 --- a/oox/inc/oox/ppt/pptimport.hxx +++ b/oox/inc/oox/ppt/pptimport.hxx @@ -68,6 +68,7 @@ public: private: virtual GraphicHelper* implCreateGraphicHelper() const; + virtual ::oox::ole::VbaProject* implCreateVbaProject() const; virtual ::rtl::OUString implGetImplementationName() const; private: diff --git a/oox/inc/oox/ppt/pptshape.hxx b/oox/inc/oox/ppt/pptshape.hxx index 3376e5bb1ace..be200859c6e6 100644 --- a/oox/inc/oox/ppt/pptshape.hxx +++ b/oox/inc/oox/ppt/pptshape.hxx @@ -48,7 +48,7 @@ public: using oox::drawingml::Shape::addShape; // addShape is creating and inserting the corresponding XShape. void addShape( - const oox::core::XmlFilterBase& rFilterBase, + oox::core::XmlFilterBase& rFilterBase, const SlidePersist& rPersist, const oox::drawingml::Theme* pTheme, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, diff --git a/oox/inc/oox/ppt/slidepersist.hxx b/oox/inc/oox/ppt/slidepersist.hxx index 31156a56ee84..e8c5d21448ce 100644 --- a/oox/inc/oox/ppt/slidepersist.hxx +++ b/oox/inc/oox/ppt/slidepersist.hxx @@ -111,7 +111,7 @@ public: oox::vml::Drawing* getDrawing() { return mpDrawingPtr.get(); } - void createXShapes( const oox::core::XmlFilterBase& rFilterBase ); + void createXShapes( oox::core::XmlFilterBase& rFilterBase ); void createBackground( const oox::core::XmlFilterBase& rFilterBase ); void applyTextStyles( const oox::core::XmlFilterBase& rFilterBase ); diff --git a/oox/inc/oox/vml/vmldrawing.hxx b/oox/inc/oox/vml/vmldrawing.hxx index 7bbeaef2f50d..0d87dae3138b 100644 --- a/oox/inc/oox/vml/vmldrawing.hxx +++ b/oox/inc/oox/vml/vmldrawing.hxx @@ -30,6 +30,7 @@ #include <map> #include <memory> +#include <vector> #include "oox/ole/oleobjecthelper.hxx" namespace com { namespace sun { namespace star { @@ -37,17 +38,21 @@ namespace com { namespace sun { namespace star { namespace awt { class XControlModel; } namespace drawing { class XDrawPage; } namespace drawing { class XShape; } + namespace drawing { class XShapes; } } } } -namespace oox { namespace core { class XmlFilterBase; } } -namespace oox { namespace ole { class EmbeddedForm; } } +namespace oox { + namespace core { class XmlFilterBase; } + namespace ole { class EmbeddedControl; } + namespace ole { class EmbeddedForm; } +} namespace oox { namespace vml { class ShapeBase; class ShapeContainer; -struct ShapeClientData; +struct ClientData; // ============================================================================ @@ -114,6 +119,9 @@ public: /** Returns the form object used to process ActiveX form controls. */ ::oox::ole::EmbeddedForm& getControlForm() const; + /** Registers a block of shape identifiers reserved by this drawing. Block + size is 1024, shape identifiers are one-based (block 1 => 1025-2048). */ + void registerBlockId( sal_Int32 nBlockId ); /** Registers the passed embedded OLE object. The related shape will then load the OLE object data from the specified fragment. */ void registerOleObject( const OleObjectInfo& rOleObject ); @@ -125,36 +133,65 @@ public: void finalizeFragmentImport(); /** Creates and inserts all UNO shapes into the passed container. The virtual - function notifyShapeInserted() will be called for each new shape. */ + function notifyXShapeInserted() will be called for each new shape. */ void convertAndInsert() const; + /** Returns the local shape index from the passed global shape identifier. */ + sal_Int32 getLocalShapeIndex( const ::rtl::OUString& rShapeId ) const; /** Returns the registered info structure for an OLE object, if extant. */ const OleObjectInfo* getOleObjectInfo( const ::rtl::OUString& rShapeId ) const; /** Returns the registered info structure for a form control, if extant. */ const ControlInfo* getControlInfo( const ::rtl::OUString& rShapeId ) const; + /** Creates a new UNO shape object, inserts it into the passed UNO shape + container, and sets the shape position and size. */ + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + createAndInsertXShape( + const ::rtl::OUString& rService, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, + const ::com::sun::star::awt::Rectangle& rShapeRect ) const; + + /** Creates a new UNO shape object for a form control, inserts the control + model into the form, and the shape into the passed UNO shape container. */ + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + createAndInsertXControlShape( + const ::oox::ole::EmbeddedControl& rControl, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, + const ::com::sun::star::awt::Rectangle& rShapeRect, + sal_Int32& rnCtrlIndex ) const; + /** Derived classes may disable conversion of specific shapes. */ virtual bool isShapeSupported( const ShapeBase& rShape ) const; + /** Derived classes may return additional base names for automatic shape + name creation. */ + virtual ::rtl::OUString getShapeBaseName( const ShapeBase& rShape ) const; + /** Derived classes may calculate the shape rectangle from a non-standard anchor information string. */ - virtual bool convertShapeClientAnchor( + virtual bool convertClientAnchor( ::com::sun::star::awt::Rectangle& orShapeRect, const ::rtl::OUString& rShapeAnchor ) const; - /** Derived classes may convert 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 ShapeClientData& rClientData ) const; - - /** Derived classes may want to know that a shape has been inserted. Will - be called from the convertAndInsert() implementation. */ - virtual void notifyShapeInserted( + /** Derived classes create a UNO shape according to the passed shape model. + Called for shape models that specify being under host control. */ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + createAndInsertClientXShape( + const ShapeBase& rShape, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, + const ::com::sun::star::awt::Rectangle& rShapeRect ) const; + + /** Derived classes may want to know that a UNO shape has been inserted. + Will be called from the convertAndInsert() implementation. + @param bGroupChild True = inserted into a group shape, + false = inserted directly into this drawing. */ + virtual void notifyXShapeInserted( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, - const ::com::sun::star::awt::Rectangle& rShapeRect ); + const ::com::sun::star::awt::Rectangle& rShapeRect, + const ShapeBase& rShape, bool bGroupChild ); private: + typedef ::std::vector< sal_Int32 > BlockIdVector; typedef ::std::auto_ptr< ::oox::ole::EmbeddedForm > EmbeddedFormPtr; typedef ::std::auto_ptr< ShapeContainer > ShapeContainerPtr; typedef ::std::map< ::rtl::OUString, OleObjectInfo > OleObjectInfoMap; @@ -163,7 +200,8 @@ private: ::oox::core::XmlFilterBase& mrFilter; /// Filter object that imports/exports the VML drawing. ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XDrawPage > mxDrawPage; /// UNO draw page used to insert the shapes. - mutable EmbeddedFormPtr mxCtrlForm; /// The control form used to process ActiveX controls. + mutable EmbeddedFormPtr mxCtrlForm; /// The control form used to process embedded controls. + mutable BlockIdVector maBlockIds; /// Block identifiers used by this drawing. ShapeContainerPtr mxShapes; /// All shapes and shape templates. OleObjectInfoMap maOleObjects; /// Info about all embedded OLE objects, mapped by shape id. ControlInfoMap maControls; /// Info about all embedded form controls, mapped by control name. diff --git a/oox/inc/oox/vml/vmlformatting.hxx b/oox/inc/oox/vml/vmlformatting.hxx index b496fed6d2e0..934be61e5a65 100644 --- a/oox/inc/oox/vml/vmlformatting.hxx +++ b/oox/inc/oox/vml/vmlformatting.hxx @@ -34,6 +34,7 @@ namespace oox { class GraphicHelper; class ModelObjectHelper; class PropertyMap; + namespace drawingml { class Color; } } namespace oox { @@ -112,6 +113,35 @@ public: bool bPixelX, bool bDefaultAsPixel ); + /** Converts VML color attributes to a DrawingML color. + + @param roVmlColor The VML string representation of the color. If + existing, this can be a 3-digit or 6-digit hexadecimal RGB value + with leading '#' character, a predefined color name (e.g. 'black', + 'red', etc.), the index into an application defined color palette + in brackets with leading color name (e.g. 'red [9]' or + 'windowColor [64]'), or a color modifier used in one-color + gradients (e.g. 'fill darken(128)' or 'fill lighten(0)'). + + @param roVmlOpacity The opacity of the color. If existing, this should + be a floating-point value in the range [0.0;1.0]. + + @param nDefaultRgb Deafult RGB color used if the parameter roVmlColor + is empty. + + @param nPrimaryRgb If set to something else than API_RGB_TRANSPARENT, + specifies the color to be used to resolve the color modifiers used + in one-color gradients. + + @return The resulting DrawingML color. + */ + static ::oox::drawingml::Color decodeColor( + const GraphicHelper& rGraphicHelper, + const OptValue< ::rtl::OUString >& roVmlColor, + const OptValue< double >& roVmlOpacity, + sal_Int32 nDefaultRgb, + sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT ); + private: ConversionHelper(); ~ConversionHelper(); diff --git a/oox/inc/oox/vml/vmlshape.hxx b/oox/inc/oox/vml/vmlshape.hxx index 76599a787306..ee95c6b61e29 100644 --- a/oox/inc/oox/vml/vmlshape.hxx +++ b/oox/inc/oox/vml/vmlshape.hxx @@ -45,6 +45,19 @@ namespace vml { class Drawing; struct ShapeParentAnchor; class ShapeContainer; +class TextBox; + +// ============================================================================ + +const sal_Int32 VML_CLIENTDATA_UNCHECKED = 0; +const sal_Int32 VML_CLIENTDATA_CHECKED = 1; +const sal_Int32 VML_CLIENTDATA_MIXED = 2; + +const sal_Int32 VML_CLIENTDATA_TEXT = 0; +const sal_Int32 VML_CLIENTDATA_INTEGER = 1; +const sal_Int32 VML_CLIENTDATA_NUMBER = 2; +const sal_Int32 VML_CLIENTDATA_REFERENCE = 3; +const sal_Int32 VML_CLIENTDATA_FORMULA = 4; // ============================================================================ @@ -52,7 +65,7 @@ class ShapeContainer; struct ShapeTypeModel { ::rtl::OUString maShapeId; /// Unique identifier of the shape. - ::rtl::OUString maName; /// Name of the shape, if present. + ::rtl::OUString maShapeName; /// Name of the shape, if present. OptValue< sal_Int32 > moShapeType; /// Builtin shape type identifier. OptValue< Int32Pair > moCoordPos; /// Top-left position of coordinate system for children scaling. @@ -93,6 +106,8 @@ public: /** Returns the shape identifier (which is unique through the containing drawing). */ inline const ::rtl::OUString& getShapeId() const { return maTypeModel.maShapeId; } + /** Returns the application defined shape type. */ + sal_Int32 getShapeType() const; /** Returns the fragment path to the embedded graphic used by this shape. */ ::rtl::OUString getGraphicPath() const; @@ -116,19 +131,39 @@ protected: // ============================================================================ /** Excel specific shape client data (such as cell anchor). */ -struct ShapeClientData +struct ClientData { ::rtl::OUString maAnchor; /// Cell anchor as comma-separated string. - ::rtl::OUString maPictureLink; /// Target cell range of picture links. - ::rtl::OUString maLinkedCell; /// Link to value cell associated to the control. - ::rtl::OUString maSourceRange; /// Link to cell range used as data source for the control. + ::rtl::OUString maFmlaMacro; /// Link to macro associated to the control. + ::rtl::OUString maFmlaPict; /// Target cell range of picture links. + ::rtl::OUString maFmlaLink; /// Link to value cell associated to the control. + ::rtl::OUString maFmlaRange; /// Link to cell range used as data source for the control. + ::rtl::OUString maFmlaGroup; /// Link to value cell associated to a group of option buttons. sal_Int32 mnObjType; /// Type of the shape. + sal_Int32 mnTextHAlign; /// Horizontal text alignment. + sal_Int32 mnTextVAlign; /// Vertical text alignment. sal_Int32 mnCol; /// Column index for spreadsheet cell note. sal_Int32 mnRow; /// Row index for spreadsheet cell note. + sal_Int32 mnChecked; /// State for checkboxes and option buttons. + sal_Int32 mnDropStyle; /// Drop down box style (read-only or editable). + sal_Int32 mnDropLines; /// Number of lines in drop down box. + sal_Int32 mnVal; /// Current value of spin buttons and scroll bars. + sal_Int32 mnMin; /// Minimum value of spin buttons and scroll bars. + sal_Int32 mnMax; /// Maximum value of spin buttons and scroll bars. + sal_Int32 mnInc; /// Small increment of spin buttons and scroll bars. + sal_Int32 mnPage; /// Large increment of spin buttons and scroll bars. + sal_Int32 mnSelType; /// Listbox selection type. + sal_Int32 mnVTEdit; /// Data type of the textbox. bool mbPrintObject; /// True = print the object. bool mbVisible; /// True = cell note is visible. - - explicit ShapeClientData(); + bool mbDde; /// True = object is linked through DDE. + bool mbNo3D; /// True = flat style, false = 3D style. + bool mbNo3D2; /// True = flat style, false = 3D style (listboxes and dropdowns). + bool mbMultiLine; /// True = textbox allows line breaks. + bool mbVScroll; /// True = textbox has a vertical scrollbar. + bool mbSecretEdit; /// True = textbox is a password edit field. + + explicit ClientData(); }; // ---------------------------------------------------------------------------- @@ -136,16 +171,21 @@ struct ShapeClientData struct ShapeModel { typedef ::std::vector< ::com::sun::star::awt::Point > PointVector; - typedef ::std::auto_ptr< ShapeClientData > ShapeClientDataPtr; + typedef ::std::auto_ptr< TextBox > TextBoxPtr; + typedef ::std::auto_ptr< ClientData > ClientDataPtr; ::rtl::OUString maType; /// Shape template with default properties. PointVector maPoints; /// Points for the polyline shape. - ShapeClientDataPtr mxClientData; /// Excel specific shape client data. + TextBoxPtr mxTextBox; /// Text contents and properties. + ClientDataPtr mxClientData; /// Excel specific client data. explicit ShapeModel(); + ~ShapeModel(); + /** Creates and returns a new shape textbox structure. */ + TextBox& createTextBox(); /** Creates and returns a new shape client data structure. */ - ShapeClientData& createClientData(); + ClientData& createClientData(); }; // ---------------------------------------------------------------------------- @@ -160,9 +200,17 @@ public: /** Returns read access to the shape model structure. */ inline const ShapeModel& getShapeModel() const { return maShapeModel; } + /** Returns read access to the shape textbox. */ + inline const TextBox* getTextBox() const { return maShapeModel.mxTextBox.get(); } + /** Returns read access to the shape client data structure. */ + inline const ClientData* getClientData() const { return maShapeModel.mxClientData.get(); } + /** Final processing after import of the drawing fragment. */ virtual void finalizeFragmentImport(); + /** Returns the real shape name if existing, or a generated shape name. */ + ::rtl::OUString getShapeName() const; + /** Returns the shape template with the passed identifier from the child shapes. */ virtual const ShapeType* getChildTypeById( const ::rtl::OUString& rShapeId ) const; /** Returns the shape with the passed identifier from the child shapes. */ diff --git a/oox/inc/oox/vml/vmlshapecontainer.hxx b/oox/inc/oox/vml/vmlshapecontainer.hxx index d4f9ec7e7f8e..e1df24a9a6f8 100644 --- a/oox/inc/oox/vml/vmlshapecontainer.hxx +++ b/oox/inc/oox/vml/vmlshapecontainer.hxx @@ -59,6 +59,9 @@ public: explicit ShapeContainer( Drawing& rDrawing ); ~ShapeContainer(); + /** Returns the drawing this shape container is part of. */ + inline Drawing& getDrawing() { return mrDrawing; } + /** Creates and returns a new shape template object. */ ShapeType& createShapeType(); /** Creates and returns a new shape object of the specified type. */ diff --git a/oox/inc/oox/vml/vmlshapecontext.hxx b/oox/inc/oox/vml/vmlshapecontext.hxx index 92253e461227..7236fe7fef2c 100644 --- a/oox/inc/oox/vml/vmlshapecontext.hxx +++ b/oox/inc/oox/vml/vmlshapecontext.hxx @@ -33,10 +33,12 @@ namespace oox { namespace vml { +class Drawing; + struct ShapeTypeModel; class ShapeType; -struct ShapeClientData; +struct ClientData; struct ShapeModel; class ShapeBase; class GroupShape; @@ -45,20 +47,38 @@ class ShapeContainer; // ============================================================================ -class ShapeClientDataContext : public ::oox::core::ContextHandler2 +class ShapeLayoutContext : public ::oox::core::ContextHandler2 +{ +public: + explicit ShapeLayoutContext( + ::oox::core::ContextHandler2Helper& rParent, + Drawing& rDrawing ); + + virtual ::oox::core::ContextHandlerRef + onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); + +private: + Drawing& mrDrawing; +}; + +// ============================================================================ + +class ClientDataContext : public ::oox::core::ContextHandler2 { public: - explicit ShapeClientDataContext( + explicit ClientDataContext( ::oox::core::ContextHandler2Helper& rParent, - const AttributeList& rAttribs, - ShapeClientData& rClientData ); + ClientData& rClientData, + const AttributeList& rAttribs ); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); private: - ShapeClientData& mrClientData; + ClientData& mrClientData; + ::rtl::OUString maElementText; }; // ============================================================================ @@ -69,9 +89,9 @@ public: static ::oox::core::ContextHandlerRef createShapeContext( ::oox::core::ContextHandler2Helper& rParent, + ShapeContainer& rShapes, sal_Int32 nElement, - const AttributeList& rAttribs, - ShapeContainer& rShapes ); + const AttributeList& rAttribs ); protected: explicit ShapeContextBase( ::oox::core::ContextHandler2Helper& rParent ); @@ -84,8 +104,8 @@ class ShapeTypeContext : public ShapeContextBase public: explicit ShapeTypeContext( ::oox::core::ContextHandler2Helper& rParent, - const AttributeList& rAttribs, - ShapeType& rShapeType ); + ShapeType& rShapeType, + const AttributeList& rAttribs ); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); @@ -108,8 +128,8 @@ class ShapeContext : public ShapeTypeContext public: explicit ShapeContext( ::oox::core::ContextHandler2Helper& rParent, - const AttributeList& rAttribs, - ShapeBase& rShape ); + ShapeBase& rShape, + const AttributeList& rAttribs ); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); @@ -129,8 +149,8 @@ class GroupShapeContext : public ShapeContext public: explicit GroupShapeContext( ::oox::core::ContextHandler2Helper& rParent, - const AttributeList& rAttribs, - GroupShape& rShape ); + GroupShape& rShape, + const AttributeList& rAttribs ); virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); diff --git a/oox/inc/oox/vml/vmltextbox.hxx b/oox/inc/oox/vml/vmltextbox.hxx new file mode 100755 index 000000000000..5aedaf86bc74 --- /dev/null +++ b/oox/inc/oox/vml/vmltextbox.hxx @@ -0,0 +1,95 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_VML_VMLTEXTBOX_HXX +#define OOX_VML_VMLTEXTBOX_HXX + +#include <vector> +#include <rtl/ustring.hxx> +#include "oox/helper/helper.hxx" + +namespace oox { +namespace vml { + +// ============================================================================ + +/** Font settings for a text portion in a textbox. */ +struct TextFontModel +{ + OptValue< ::rtl::OUString > moName; /// Font name. + OptValue< ::rtl::OUString > moColor; /// Font color, HTML encoded, sort of. + OptValue< sal_Int32 > monSize; /// Font size in twips. + OptValue< sal_Int32 > monUnderline; /// Single or double underline. + OptValue< sal_Int32 > monEscapement; /// Subscript or superscript. + OptValue< bool > mobBold; + OptValue< bool > mobItalic; + OptValue< bool > mobStrikeout; + + explicit TextFontModel(); +}; + +// ============================================================================ + +/** A text portion in a textbox with the same formatting for all characters. */ +struct TextPortionModel +{ + TextFontModel maFont; + ::rtl::OUString maText; + + explicit TextPortionModel( const TextFontModel& rFont, const ::rtl::OUString& rText ); +}; + +// ============================================================================ + +/** The textbox contains all text contents and properties. */ +class TextBox +{ +public: + explicit TextBox(); + + /** Appends a new text portion to the textbox. */ + void appendPortion( const TextFontModel& rFont, const ::rtl::OUString& rText ); + + /** Returns the current number of text portions. */ + inline size_t getPortionCount() const { return maPortions.size(); } + /** Returns the font settings of the first text portion. */ + const TextFontModel* getFirstFont() const; + /** Returns the entire text of all text portions. */ + ::rtl::OUString getText() const; + +private: + typedef ::std::vector< TextPortionModel > PortionVector; + + PortionVector maPortions; +}; + +// ============================================================================ + +} // namespace vml +} // namespace oox + +#endif diff --git a/oox/inc/oox/vml/vmltextboxcontext.hxx b/oox/inc/oox/vml/vmltextboxcontext.hxx new file mode 100755 index 000000000000..1dc8832f9cc4 --- /dev/null +++ b/oox/inc/oox/vml/vmltextboxcontext.hxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef OOX_VML_VMLTEXTBOXCONTEXT_HXX +#define OOX_VML_VMLTEXTBOXCONTEXT_HXX + +#include "oox/core/contexthandler2.hxx" +#include "oox/vml/vmltextbox.hxx" + +namespace oox { +namespace vml { + +// ============================================================================ + +class TextPortionContext : public ::oox::core::ContextHandler2 +{ +public: + explicit TextPortionContext( + ::oox::core::ContextHandler2Helper& rParent, + TextBox& rTextBox, + const TextFontModel& rParentFont, + sal_Int32 nElement, + const AttributeList& rAttribs ); + + virtual ::oox::core::ContextHandlerRef + onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); + +private: + TextBox& mrTextBox; + TextFontModel maFont; + size_t mnInitialPortions; +}; + +// ============================================================================ + +class TextBoxContext : public ::oox::core::ContextHandler2 +{ +public: + explicit TextBoxContext( + ::oox::core::ContextHandler2Helper& rParent, + TextBox& rTextBox, + const AttributeList& rAttribs ); + + virtual ::oox::core::ContextHandlerRef + onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); + +private: + TextBox& mrTextBox; +}; + +// ============================================================================ + +} // namespace vml +} // namespace oox + +#endif diff --git a/oox/inc/oox/xls/autofiltercontext.hxx b/oox/inc/oox/xls/autofiltercontext.hxx index ccef6972e871..83b1f4ff0ee8 100644 --- a/oox/inc/oox/xls/autofiltercontext.hxx +++ b/oox/inc/oox/xls/autofiltercontext.hxx @@ -85,7 +85,7 @@ protected: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); virtual void onStartElement( const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onEndElement(); private: /** Initializes data members to prepare for autofilter parsing. Call this diff --git a/oox/inc/oox/xls/chartsheetfragment.hxx b/oox/inc/oox/xls/chartsheetfragment.hxx index dc8e0f85fd13..58a6fdb5b54a 100644 --- a/oox/inc/oox/xls/chartsheetfragment.hxx +++ b/oox/inc/oox/xls/chartsheetfragment.hxx @@ -48,7 +48,7 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); diff --git a/oox/inc/oox/xls/commentsfragment.hxx b/oox/inc/oox/xls/commentsfragment.hxx index 584c6a2bb340..97788d635c15 100644 --- a/oox/inc/oox/xls/commentsfragment.hxx +++ b/oox/inc/oox/xls/commentsfragment.hxx @@ -46,7 +46,8 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); virtual void onEndRecord(); diff --git a/oox/inc/oox/xls/condformatcontext.hxx b/oox/inc/oox/xls/condformatcontext.hxx index 799e3127b7a3..492c1db1beb7 100644 --- a/oox/inc/oox/xls/condformatcontext.hxx +++ b/oox/inc/oox/xls/condformatcontext.hxx @@ -46,7 +46,7 @@ protected: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); virtual void onStartElement( const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); virtual void onStartRecord( RecordInputStream& rStrm ); diff --git a/oox/inc/oox/xls/defnamesbuffer.hxx b/oox/inc/oox/xls/defnamesbuffer.hxx index 45208f0ac344..fa9715022c9f 100644 --- a/oox/inc/oox/xls/defnamesbuffer.hxx +++ b/oox/inc/oox/xls/defnamesbuffer.hxx @@ -138,6 +138,8 @@ public: inline bool isBuiltinName() const { return mcBuiltinId != OOX_DEFNAME_UNKNOWN; } /** Returns true, if this defined name is a macro function call. */ inline bool isMacroFunction() const { return maModel.mbMacro && maModel.mbFunction; } + /** Returns true, if this defined name is a reference to a VBA macro. */ + inline bool isVBName() const { return maModel.mbMacro && maModel.mbVBName; } /** Returns true, if this defined name is global in the document. */ inline bool isGlobalName() const { return mnCalcSheet < 0; } @@ -218,4 +220,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/xls/drawingfragment.hxx b/oox/inc/oox/xls/drawingfragment.hxx index 95973e55c655..0b4dba0bbd53 100644 --- a/oox/inc/oox/xls/drawingfragment.hxx +++ b/oox/inc/oox/xls/drawingfragment.hxx @@ -31,15 +31,25 @@ #include <com/sun/star/awt/Rectangle.hpp> #include <com/sun/star/awt/Size.hpp> #include "oox/drawingml/shape.hxx" +#include "oox/drawingml/shapegroupcontext.hxx" #include "oox/ole/axcontrol.hxx" +#include "oox/ole/vbaproject.hxx" #include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmldrawingfragment.hxx" +#include "oox/vml/vmltextbox.hxx" #include "oox/xls/excelhandlers.hxx" +namespace oox { namespace ole { + struct AxFontData; + class AxMorphDataModelBase; +} } + namespace oox { namespace xls { // ============================================================================ +// DrawingML +// ============================================================================ /** Absolute position in spreadsheet (in EMUs) independent from cells. */ struct AnchorPosModel : public ::oox::drawingml::EmuPoint @@ -101,6 +111,7 @@ public: void importClientData( const AttributeList& rAttribs ); /** Sets an attribute of the cell-dependent anchor position from xdr:from and xdr:to elements. */ void setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, const ::rtl::OUString& rValue ); + /** Imports and converts the VML specific client anchor. */ void importVmlAnchor( const ::rtl::OUString& rAnchor ); /** Returns true, if the anchor contains valid position and size settings. */ @@ -132,6 +143,67 @@ typedef ::boost::shared_ptr< ShapeAnchor > ShapeAnchorRef; // ============================================================================ +class ShapeMacroAttacher : public ::oox::ole::VbaMacroAttacherBase +{ +public: + explicit ShapeMacroAttacher( const ::rtl::OUString& rMacroName, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape ); + +private: + virtual void attachMacro( const ::rtl::OUString& rMacroUrl ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxShape; +}; + +// ============================================================================ + +class Shape : public ::oox::drawingml::Shape, public WorksheetHelper +{ +public: + explicit Shape( + const WorksheetHelper& rHelper, + const AttributeList& rAttribs, + const sal_Char* pcServiceName = 0 ); + +protected: + virtual void finalizeXShape( + ::oox::core::XmlFilterBase& rFilter, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes ); + +private: + ::rtl::OUString maMacroName; +}; + +// ============================================================================ + +/** Context handler for creation of shapes embedded in group shapes. */ +class OoxGroupShapeContext : public ::oox::drawingml::ShapeGroupContext, public WorksheetHelper +{ +public: + explicit OoxGroupShapeContext( + ::oox::core::ContextHandler& rParent, + const WorksheetHelper& rHelper, + const ::oox::drawingml::ShapePtr& rxShape ); + + static ::oox::core::ContextHandlerRef + createShapeContext( + ::oox::core::ContextHandler& rParent, + const WorksheetHelper& rHelper, + sal_Int32 nElement, + const AttributeList& rAttribs, + ::oox::drawingml::ShapePtr* pxShape = 0 ); + +protected: + virtual ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastContextHandler > SAL_CALL + createFastChildContext( + sal_Int32 nElement, + const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XFastAttributeList >& rxAttribs ) + throw (::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException); +}; + +// ============================================================================ + /** Fragment handler for a complete sheet drawing. */ class OoxDrawingFragment : public OoxWorksheetFragmentBase { @@ -144,7 +216,8 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); private: ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > @@ -156,6 +229,27 @@ private: }; // ============================================================================ +// VML +// ============================================================================ + +class VmlControlMacroAttacher : public ::oox::ole::VbaMacroAttacherBase +{ +public: + explicit VmlControlMacroAttacher( const ::rtl::OUString& rMacroName, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >& rxCtrlFormIC, + sal_Int32 nCtrlIndex, sal_Int32 nCtrlType, sal_Int32 nDropStyle ); + +private: + virtual void attachMacro( const ::rtl::OUString& rMacroUrl ); + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer > mxCtrlFormIC; + sal_Int32 mnCtrlIndex; + sal_Int32 mnCtrlType; + sal_Int32 mnDropStyle; +}; + +// ============================================================================ class VmlDrawing : public ::oox::vml::Drawing, public WorksheetHelper { @@ -168,24 +262,47 @@ public: /** Filters cell note shapes. */ virtual bool isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const; + /** Returns additional base names for automatic shape name creation. */ + virtual ::rtl::OUString getShapeBaseName( const ::oox::vml::ShapeBase& rShape ) const; + /** Calculates the shape rectangle from a cell anchor string. */ - virtual bool convertShapeClientAnchor( + virtual bool convertClientAnchor( ::com::sun::star::awt::Rectangle& orShapeRect, const ::rtl::OUString& rShapeAnchor ) const; - /** 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 ::oox::vml::ShapeClientData& rClientData ) const; + /** Creates a UNO control shape for legacy drawing controls. */ + virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + createAndInsertClientXShape( + const ::oox::vml::ShapeBase& rShape, + const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, + const ::com::sun::star::awt::Rectangle& rShapeRect ) const; /** Updates the bounding box covering all shapes of this drawing. */ - virtual void notifyShapeInserted( + virtual void notifyXShapeInserted( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape, - const ::com::sun::star::awt::Rectangle& rShapeRect ); + const ::com::sun::star::awt::Rectangle& rShapeRect, + const ::oox::vml::ShapeBase& rShape, bool bGroupChild ); + +private: + /** Converts the passed VML textbox text color to an OLE color. */ + sal_uInt32 convertControlTextColor( const ::rtl::OUString& rTextColor ) const; + /** Converts the passed VML textbox font to an ActiveX form control font. */ + void convertControlFontData( + ::oox::ole::AxFontData& rAxFontData, sal_uInt32& rnOleTextColor, + const ::oox::vml::TextFontModel& rFontModel ) const; + /** Converts the caption, the font settings, and the horizontal alignment + from the passed VML textbox to ActiveX form control settings. */ + void convertControlText( + ::oox::ole::AxFontData& rAxFontData, sal_uInt32& rnOleTextColor, ::rtl::OUString& rCaption, + const ::oox::vml::TextBox* pTextBox, sal_Int32 nTextHAlign ) const; + /** Converts the passed VML shape background formatting to ActiveX control formatting. */ + void convertControlBackground( + ::oox::ole::AxMorphDataModelBase& rAxModel, + const ::oox::vml::ShapeBase& rShape ) const; private: ::oox::ole::ControlConverter maControlConv; + ::oox::vml::TextFontModel maListBoxFont; }; // ============================================================================ @@ -207,4 +324,3 @@ protected: } // namespace oox #endif - diff --git a/oox/inc/oox/xls/excelfilter.hxx b/oox/inc/oox/xls/excelfilter.hxx index b5d7a97f33b5..0b293cf57193 100644 --- a/oox/inc/oox/xls/excelfilter.hxx +++ b/oox/inc/oox/xls/excelfilter.hxx @@ -72,6 +72,7 @@ public: private: virtual GraphicHelper* implCreateGraphicHelper() const; + virtual ::oox::ole::VbaProject* implCreateVbaProject() const; virtual ::rtl::OUString implGetImplementationName() const; }; @@ -89,6 +90,7 @@ public: private: virtual GraphicHelper* implCreateGraphicHelper() const; + virtual ::oox::ole::VbaProject* implCreateVbaProject() const; virtual ::rtl::OUString implGetImplementationName() const; }; @@ -98,4 +100,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/xls/excelvbaproject.hxx b/oox/inc/oox/xls/excelvbaproject.hxx index 9726cbdc923c..f2a9aebd988a 100755 --- a/oox/inc/oox/xls/excelvbaproject.hxx +++ b/oox/inc/oox/xls/excelvbaproject.hxx @@ -41,10 +41,10 @@ namespace xls { // ============================================================================ /** Special implementation of the VBA project for the Excel filters. */ -class OOX_DLLPUBLIC VbaProject : public ::oox::ole::VbaProject +class OOX_DLLPUBLIC ExcelVbaProject : public ::oox::ole::VbaProject { public: - explicit VbaProject( + explicit ExcelVbaProject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rxGlobalFactory, const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& rxDocument ); @@ -53,7 +53,9 @@ public: protected: /** Adds dummy modules for sheets without imported code name. */ - virtual void prepareModuleImport(); + virtual void prepareImport(); + /** Attaches document and sheet events to macros. */ + virtual void finalizeImport(); private: /** Attaches VBA macros to all supported document events. */ diff --git a/oox/inc/oox/xls/externallinkbuffer.hxx b/oox/inc/oox/xls/externallinkbuffer.hxx index b9980cc21e2f..7a4cf26fecb2 100644 --- a/oox/inc/oox/xls/externallinkbuffer.hxx +++ b/oox/inc/oox/xls/externallinkbuffer.hxx @@ -248,6 +248,9 @@ public: /** Imports the EXTERNALNAME record from the passed stream. */ void importExternalName( BiffInputStream& rStrm ); + /** Sets the link type to 'self reference'. */ + inline void setSelfLinkType() { meLinkType = LINKTYPE_SELF; } + /** Returns the type of this external link. */ inline ExternalLinkType getLinkType() const { return meLinkType; } /** Returns true, if the link refers to the current workbook. */ @@ -368,7 +371,7 @@ public: getLinkInfos() const; /** Returns the external link for the passed reference identifier. */ - ExternalLinkRef getExternalLink( sal_Int32 nRefId ) const; + ExternalLinkRef getExternalLink( sal_Int32 nRefId, bool bUseRefSheets = true ) const; /** Returns the sheet range for the specified reference (BIFF2-BIFF5 only). */ LinkSheetRange getSheetRange( sal_Int32 nRefId, sal_Int16 nTabId1, sal_Int16 nTabId2 ) const; @@ -386,6 +389,7 @@ private: typedef RefVector< ExternalLink > ExternalLinkVec; typedef ::std::vector< RefSheetsModel > RefSheetsModelVec; + ExternalLinkRef mxSelfRef; /// Implicit self reference at index 0. ExternalLinkVec maLinks; /// List of link structures for all kinds of links. ExternalLinkVec maExtLinks; /// Real external links needed for formula parser. RefSheetsModelVec maRefSheets; /// Sheet indexes for reference ids. @@ -398,4 +402,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/xls/externallinkfragment.hxx b/oox/inc/oox/xls/externallinkfragment.hxx index ec310974818a..c651f4f2f0a5 100644 --- a/oox/inc/oox/xls/externallinkfragment.hxx +++ b/oox/inc/oox/xls/externallinkfragment.hxx @@ -54,7 +54,7 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); @@ -97,7 +97,8 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); diff --git a/oox/inc/oox/xls/formulaparser.hxx b/oox/inc/oox/xls/formulaparser.hxx index 0227e8efee6d..599a8af7bf46 100644 --- a/oox/inc/oox/xls/formulaparser.hxx +++ b/oox/inc/oox/xls/formulaparser.hxx @@ -157,6 +157,9 @@ public: BiffInputStream& rStrm, const sal_uInt16* pnFmlaSize = 0 ) const; + /** Converts the passed formula to a macro name for a drawing shape. */ + ::rtl::OUString importMacroName( const ::rtl::OUString& rFormulaString ); + private: ::std::auto_ptr< FormulaParserImpl > mxImpl; }; @@ -167,4 +170,3 @@ private: } // namespace oox #endif - diff --git a/oox/inc/oox/xls/richstringcontext.hxx b/oox/inc/oox/xls/richstringcontext.hxx index 53882641df7e..7b5992db2871 100644 --- a/oox/inc/oox/xls/richstringcontext.hxx +++ b/oox/inc/oox/xls/richstringcontext.hxx @@ -46,7 +46,7 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); private: RichStringRef mxString; /// Processed string. diff --git a/oox/inc/oox/xls/sheetdatacontext.hxx b/oox/inc/oox/xls/sheetdatacontext.hxx index a77f4b285fa4..7fd7c9b915b5 100644 --- a/oox/inc/oox/xls/sheetdatacontext.hxx +++ b/oox/inc/oox/xls/sheetdatacontext.hxx @@ -54,7 +54,8 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); diff --git a/oox/inc/oox/xls/workbookfragment.hxx b/oox/inc/oox/xls/workbookfragment.hxx index f9f0bb25c78f..b499704e62cb 100644 --- a/oox/inc/oox/xls/workbookfragment.hxx +++ b/oox/inc/oox/xls/workbookfragment.hxx @@ -49,7 +49,7 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); diff --git a/oox/inc/oox/xls/worksheetfragment.hxx b/oox/inc/oox/xls/worksheetfragment.hxx index 7234153d7dd3..6b3b5357bb44 100644 --- a/oox/inc/oox/xls/worksheetfragment.hxx +++ b/oox/inc/oox/xls/worksheetfragment.hxx @@ -44,7 +44,8 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); + virtual void onEndElement(); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); @@ -74,7 +75,7 @@ protected: // oox.core.ContextHandler2Helper interface ------------------------------- virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); - virtual void onEndElement( const ::rtl::OUString& rChars ); + virtual void onCharacters( const ::rtl::OUString& rChars ); virtual ::oox::core::ContextHandlerRef onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ); diff --git a/oox/source/core/binarycodec.cxx b/oox/source/core/binarycodec.cxx index 6127524c2aae..b2c117a12d90 100644 --- a/oox/source/core/binarycodec.cxx +++ b/oox/source/core/binarycodec.cxx @@ -26,6 +26,7 @@ ************************************************************************/ #include "oox/core/binarycodec.hxx" + #include <algorithm> #include <string.h> #include "oox/helper/attributelist.hxx" @@ -387,4 +388,3 @@ bool BinaryCodec_RCF::skip( sal_Int32 nBytes ) } // namespace core } // namespace oox - diff --git a/oox/source/core/binaryfilterbase.cxx b/oox/source/core/binaryfilterbase.cxx index f308f02ac9dc..9eb476920a4b 100644 --- a/oox/source/core/binaryfilterbase.cxx +++ b/oox/source/core/binaryfilterbase.cxx @@ -26,19 +26,22 @@ ************************************************************************/ #include "oox/core/binaryfilterbase.hxx" -#include "oox/ole/olestorage.hxx" -using ::rtl::OUString; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::io::XInputStream; -using ::com::sun::star::io::XStream; +#include "oox/ole/olestorage.hxx" namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; + +using ::rtl::OUString; + +// ============================================================================ + BinaryFilterBase::BinaryFilterBase( const Reference< XMultiServiceFactory >& rxGlobalFactory ) : FilterBase( rxGlobalFactory ) { @@ -64,4 +67,3 @@ StorageRef BinaryFilterBase::implCreateStorage( const Reference< XStream >& rxOu } // namespace core } // namespace oox - diff --git a/oox/source/core/contexthandler.cxx b/oox/source/core/contexthandler.cxx index b9c7cb48377e..c2d6fa928576 100644 --- a/oox/source/core/contexthandler.cxx +++ b/oox/source/core/contexthandler.cxx @@ -26,21 +26,21 @@ ************************************************************************/ #include "oox/core/contexthandler.hxx" -#include "oox/core/fragmenthandler.hxx" -using ::rtl::OUString; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::xml::sax::XFastAttributeList; -using ::com::sun::star::xml::sax::XFastContextHandler; -using ::com::sun::star::xml::sax::XLocator; +#include "oox/core/fragmenthandler.hxx" namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +using ::rtl::OUString; + +// ============================================================================ + ContextHandler::ContextHandler( ContextHandler& rParent ) : ContextHandlerImplBase(), mxBaseData( rParent.mxBaseData ) @@ -150,4 +150,3 @@ void ContextHandler::endRecord( sal_Int32 ) } // namespace core } // namespace oox - diff --git a/oox/source/core/contexthandler2.cxx b/oox/source/core/contexthandler2.cxx index 0f39ba313e6b..0cb7017372da 100644 --- a/oox/source/core/contexthandler2.cxx +++ b/oox/source/core/contexthandler2.cxx @@ -28,36 +28,29 @@ #include "oox/core/contexthandler2.hxx" #include <rtl/ustrbuf.hxx> -using ::rtl::OUString; -using ::rtl::OUStringBuffer; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::xml::sax::XFastAttributeList; -using ::com::sun::star::xml::sax::XFastContextHandler; - namespace oox { namespace core { // ============================================================================ -/** Information about a processed context element. */ -struct ContextInfo +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +// ============================================================================ + +/** Information about a processed element. */ +struct ElementInfo { - OUStringBuffer maCurrChars; /// Collected characters from context. - OUStringBuffer maFinalChars; /// Finalized (stipped) characters. + OUStringBuffer maChars; /// Collected element characters. sal_Int32 mnElement; /// The element identifier. bool mbTrimSpaces; /// True = trims leading/trailing spaces from text data. - explicit ContextInfo(); + inline explicit ElementInfo() : mnElement( XML_TOKEN_INVALID ), mbTrimSpaces( false ) {} }; -ContextInfo::ContextInfo() : - mnElement( XML_TOKEN_INVALID ), - mbTrimSpaces( false ) -{ -} - // ============================================================================ ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace ) : @@ -65,7 +58,7 @@ ContextHandler2Helper::ContextHandler2Helper( bool bEnableTrimSpace ) : mnRootStackSize( 0 ), mbEnableTrimSpace( bEnableTrimSpace ) { - pushContextInfo( XML_ROOT_CONTEXT ); + pushElementInfo( XML_ROOT_CONTEXT ); } ContextHandler2Helper::ContextHandler2Helper( const ContextHandler2Helper& rParent ) : @@ -84,7 +77,7 @@ sal_Int32 ContextHandler2Helper::getCurrentElement() const return mxContextStack->empty() ? XML_ROOT_CONTEXT : mxContextStack->back().mnElement; } -sal_Int32 ContextHandler2Helper::getPreviousElement( sal_Int32 nCountBack ) const +sal_Int32 ContextHandler2Helper::getParentElement( sal_Int32 nCountBack ) const { if( (nCountBack < 0) || (mxContextStack->size() < static_cast< size_t >( nCountBack )) ) return XML_TOKEN_INVALID; @@ -97,38 +90,39 @@ bool ContextHandler2Helper::isRootElement() const return mxContextStack->size() == mnRootStackSize + 1; } -Reference< XFastContextHandler > ContextHandler2Helper::implCreateChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) +Reference< XFastContextHandler > ContextHandler2Helper::implCreateChildContext( + sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) { - appendCollectedChars(); + // #i76091# process collected characters (calls onCharacters() if needed) + processCollectedChars(); ContextHandlerRef xContext = onCreateContext( nElement, AttributeList( rxAttribs ) ); return Reference< XFastContextHandler >( xContext.get() ); } -void ContextHandler2Helper::implStartCurrentContext( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) +void ContextHandler2Helper::implStartElement( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) { AttributeList aAttribs( rxAttribs ); - pushContextInfo( nElement ).mbTrimSpaces = aAttribs.getToken( NMSP_XML | XML_space, XML_TOKEN_INVALID ) != XML_preserve; + pushElementInfo( nElement ).mbTrimSpaces = aAttribs.getToken( NMSP_XML | XML_space, XML_TOKEN_INVALID ) != XML_preserve; onStartElement( aAttribs ); } void ContextHandler2Helper::implCharacters( const OUString& rChars ) { - // #i76091# collect characters until context ends + // #i76091# collect characters until new element starts or this element ends if( !mxContextStack->empty() ) - mxContextStack->back().maCurrChars.append( rChars ); + mxContextStack->back().maChars.append( rChars ); } -void ContextHandler2Helper::implEndCurrentContext( sal_Int32 nElement ) +void ContextHandler2Helper::implEndElement( sal_Int32 nElement ) { (void)nElement; // prevent "unused parameter" warning in product build - OSL_ENSURE( getCurrentElement() == nElement, "ContextHandler2Helper::implEndCurrentContext - context stack broken" ); + OSL_ENSURE( getCurrentElement() == nElement, "ContextHandler2Helper::implEndElement - context stack broken" ); if( !mxContextStack->empty() ) { - // #i76091# process collected characters - appendCollectedChars(); - // finalize the current context and pop context info from stack - onEndElement( mxContextStack->back().maFinalChars.makeStringAndClear() ); - popContextInfo(); + // #i76091# process collected characters (calls onCharacters() if needed) + processCollectedChars(); + onEndElement(); + popElementInfo(); } } @@ -139,7 +133,7 @@ ContextHandlerRef ContextHandler2Helper::implCreateRecordContext( sal_Int32 nRec void ContextHandler2Helper::implStartRecord( sal_Int32 nRecId, RecordInputStream& rStrm ) { - pushContextInfo( nRecId ); + pushElementInfo( nRecId ); onStartRecord( rStrm ); } @@ -149,42 +143,44 @@ void ContextHandler2Helper::implEndRecord( sal_Int32 nRecId ) OSL_ENSURE( getCurrentElement() == nRecId, "ContextHandler2Helper::implEndRecord - context stack broken" ); if( !mxContextStack->empty() ) { - // finalize the current context and pop context info from stack onEndRecord(); - popContextInfo(); + popElementInfo(); } } -ContextInfo& ContextHandler2Helper::pushContextInfo( sal_Int32 nElement ) +ElementInfo& ContextHandler2Helper::pushElementInfo( sal_Int32 nElement ) { mxContextStack->resize( mxContextStack->size() + 1 ); - ContextInfo& rInfo = mxContextStack->back(); + ElementInfo& rInfo = mxContextStack->back(); rInfo.mnElement = nElement; return rInfo; } -void ContextHandler2Helper::popContextInfo() +void ContextHandler2Helper::popElementInfo() { - OSL_ENSURE( !mxContextStack->empty(), "ContextHandler2Helper::popContextInfo - context stack broken" ); + OSL_ENSURE( !mxContextStack->empty(), "ContextHandler2Helper::popElementInfo - context stack broken" ); if( !mxContextStack->empty() ) mxContextStack->pop_back(); } -void ContextHandler2Helper::appendCollectedChars() +void ContextHandler2Helper::processCollectedChars() { - OSL_ENSURE( !mxContextStack->empty(), "ContextHandler2Helper::appendCollectedChars - no context info" ); - ContextInfo& rInfo = mxContextStack->back(); - if( rInfo.maCurrChars.getLength() > 0 ) + OSL_ENSURE( !mxContextStack->empty(), "ContextHandler2Helper::processCollectedChars - no context info" ); + ElementInfo& rInfo = mxContextStack->back(); + if( rInfo.maChars.getLength() > 0 ) { - OUString aChars = rInfo.maCurrChars.makeStringAndClear(); - rInfo.maFinalChars.append( (mbEnableTrimSpace && rInfo.mbTrimSpaces) ? aChars.trim() : aChars ); + OUString aChars = rInfo.maChars.makeStringAndClear(); + if( mbEnableTrimSpace && rInfo.mbTrimSpaces ) + aChars = aChars.trim(); + if( aChars.getLength() > 0 ) + onCharacters( aChars ); } } // ============================================================================ ContextHandler2::ContextHandler2( ContextHandler2Helper& rParent ) : - ContextHandler( rParent.queryContextHandler() ), + ContextHandler( dynamic_cast< ContextHandler& >( rParent ) ), ContextHandler2Helper( rParent ) { } @@ -193,11 +189,6 @@ ContextHandler2::~ContextHandler2() { } -ContextHandler& ContextHandler2::queryContextHandler() -{ - return *this; -} - // com.sun.star.xml.sax.XFastContextHandler interface ------------------------- Reference< XFastContextHandler > SAL_CALL ContextHandler2::createFastChildContext( @@ -209,7 +200,7 @@ Reference< XFastContextHandler > SAL_CALL ContextHandler2::createFastChildContex void SAL_CALL ContextHandler2::startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException ) { - implStartCurrentContext( nElement, rxAttribs ); + implStartElement( nElement, rxAttribs ); } void SAL_CALL ContextHandler2::characters( const OUString& rChars ) throw( SAXException, RuntimeException ) @@ -219,7 +210,7 @@ void SAL_CALL ContextHandler2::characters( const OUString& rChars ) throw( SAXEx void SAL_CALL ContextHandler2::endFastElement( sal_Int32 nElement ) throw( SAXException, RuntimeException ) { - implEndCurrentContext( nElement ); + implEndElement( nElement ); } // oox.core.RecordContext interface ------------------------------------------- @@ -250,7 +241,11 @@ void ContextHandler2::onStartElement( const AttributeList& ) { } -void ContextHandler2::onEndElement( const OUString& ) +void ContextHandler2::onCharacters( const OUString& ) +{ +} + +void ContextHandler2::onEndElement() { } @@ -271,4 +266,3 @@ void ContextHandler2::onEndRecord() } // namespace core } // namespace oox - diff --git a/oox/source/core/facreg.cxx b/oox/source/core/facreg.cxx index de6212984093..6d62f0ec34a8 100644 --- a/oox/source/core/facreg.cxx +++ b/oox/source/core/facreg.cxx @@ -37,8 +37,8 @@ #include <cppuhelper/factory.hxx> #include <uno/lbnames.h> -using namespace rtl; -using namespace com::sun::star; +using ::rtl::OUString; +using namespace ::com::sun::star; #define SERVICE( className ) \ extern OUString SAL_CALL className##_getImplementationName() throw(); \ diff --git a/oox/source/core/fasttokenhandler.cxx b/oox/source/core/fasttokenhandler.cxx index c662828bc583..547570e29439 100644 --- a/oox/source/core/fasttokenhandler.cxx +++ b/oox/source/core/fasttokenhandler.cxx @@ -26,20 +26,23 @@ ************************************************************************/ #include "oox/core/fasttokenhandler.hxx" + #include <osl/mutex.hxx> #include "oox/token/tokenmap.hxx" -using ::rtl::OUString; -using ::osl::Mutex; -using ::osl::MutexGuard; -using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::RuntimeException; - namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::uno; + +using ::osl::Mutex; +using ::osl::MutexGuard; +using ::rtl::OUString; + +// ============================================================================ + namespace { Mutex& lclGetTokenMutex() @@ -89,4 +92,3 @@ sal_Int32 FastTokenHandler::getTokenFromUTF8( const Sequence< sal_Int8 >& rIdent } // namespace core } // namespace oox - diff --git a/oox/source/core/filterbase.cxx b/oox/source/core/filterbase.cxx index fb9e43c732de..8caca4e6295a 100644..100755 --- a/oox/source/core/filterbase.cxx +++ b/oox/source/core/filterbase.cxx @@ -26,49 +26,42 @@ ************************************************************************/ #include "oox/core/filterbase.hxx" + #include <set> #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/task/XStatusIndicator.hpp> #include <com/sun/star/task/XInteractionHandler.hpp> +#include <comphelper/docpasswordhelper.hxx> +#include <comphelper/mediadescriptor.hxx> #include <osl/mutex.hxx> #include <rtl/instance.hxx> #include <rtl/uri.hxx> -#include <comphelper/docpasswordhelper.hxx> -#include <comphelper/mediadescriptor.hxx> -#include "tokens.hxx" #include "oox/helper/binaryinputstream.hxx" #include "oox/helper/binaryoutputstream.hxx" #include "oox/helper/graphichelper.hxx" #include "oox/helper/modelobjecthelper.hxx" #include "oox/ole/oleobjecthelper.hxx" +#include "oox/ole/vbaproject.hxx" +#include "tokens.hxx" + +namespace oox { +namespace core { + +// ============================================================================ + +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::graphic; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::uno; -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::RuntimeException; -using ::com::sun::star::uno::UNO_QUERY; -using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::com::sun::star::uno::UNO_SET_THROW; -using ::com::sun::star::lang::IllegalArgumentException; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::lang::XComponent; -using ::com::sun::star::beans::PropertyValue; -using ::com::sun::star::frame::XFrame; -using ::com::sun::star::frame::XModel; -using ::com::sun::star::io::XInputStream; -using ::com::sun::star::io::XOutputStream; -using ::com::sun::star::io::XStream; -using ::com::sun::star::task::XStatusIndicator; -using ::com::sun::star::task::XInteractionHandler; -using ::com::sun::star::graphic::XGraphic; using ::comphelper::MediaDescriptor; using ::comphelper::SequenceAsHashMap; using ::oox::ole::OleObjectHelper; - -namespace oox { -namespace core { +using ::oox::ole::VbaProject; +using ::rtl::OUString; // ============================================================================ @@ -133,6 +126,7 @@ struct FilterBaseImpl typedef ::boost::shared_ptr< GraphicHelper > GraphicHelperRef; typedef ::boost::shared_ptr< ModelObjectHelper > ModelObjHelperRef; typedef ::boost::shared_ptr< OleObjectHelper > OleObjHelperRef; + typedef ::boost::shared_ptr< VbaProject > VbaProjectRef; FilterDirection meDirection; SequenceAsHashMap maArguments; @@ -143,6 +137,7 @@ struct FilterBaseImpl GraphicHelperRef mxGraphicHelper; /// Graphic and graphic object handling. ModelObjHelperRef mxModelObjHelper; /// Tables to create new named drawing objects. OleObjHelperRef mxOleObjHelper; /// OLE object handling. + VbaProjectRef mxVbaProject; /// VBA project manager. Reference< XMultiServiceFactory > mxGlobalFactory; Reference< XModel > mxModel; @@ -392,6 +387,13 @@ OleObjectHelper& FilterBase::getOleObjectHelper() const return *mxImpl->mxOleObjHelper; } +VbaProject& FilterBase::getVbaProject() const +{ + if( !mxImpl->mxVbaProject ) + mxImpl->mxVbaProject.reset( implCreateVbaProject() ); + return *mxImpl->mxVbaProject; +} + OUString FilterBase::requestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const { ::std::vector< OUString > aDefaultPasswords; @@ -563,4 +565,3 @@ GraphicHelper* FilterBase::implCreateGraphicHelper() const } // namespace core } // namespace oox - diff --git a/oox/source/core/filterdetect.cxx b/oox/source/core/filterdetect.cxx index 00244c224778..8c3e64f99174 100644 --- a/oox/source/core/filterdetect.cxx +++ b/oox/source/core/filterdetect.cxx @@ -26,50 +26,38 @@ ************************************************************************/ #include "oox/core/filterdetect.hxx" + #include <com/sun/star/io/XStream.hpp> #include <com/sun/star/xml/sax/XFastParser.hpp> -#include <rtl/digest.h> -#include <openssl/evp.h> #include <comphelper/docpasswordhelper.hxx> #include <comphelper/mediadescriptor.hxx> +#include <openssl/evp.h> +#include <rtl/digest.h> +#include "oox/core/fasttokenhandler.hxx" +#include "oox/core/namespaces.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/binaryinputstream.hxx" #include "oox/helper/binaryoutputstream.hxx" #include "oox/helper/zipstorage.hxx" -#include "oox/core/fasttokenhandler.hxx" -#include "oox/core/namespaces.hxx" #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; -using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::UNO_QUERY; -using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::com::sun::star::uno::UNO_SET_THROW; -using ::com::sun::star::uno::XInterface; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::beans::NamedValue; -using ::com::sun::star::beans::PropertyValue; -using ::com::sun::star::io::XInputStream; -using ::com::sun::star::io::XOutputStream; -using ::com::sun::star::io::XStream; -using ::com::sun::star::xml::sax::InputSource; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::xml::sax::XFastAttributeList; -using ::com::sun::star::xml::sax::XFastContextHandler; -using ::com::sun::star::xml::sax::XFastParser; -using ::com::sun::star::xml::sax::XLocator; -using ::comphelper::MediaDescriptor; -using ::comphelper::SequenceAsHashMap; - namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +using ::comphelper::MediaDescriptor; +using ::comphelper::SequenceAsHashMap; +using ::rtl::OUString; + +// ============================================================================ + FilterDetectDocHandler::FilterDetectDocHandler( OUString& rFilterName ) : mrFilterName( rFilterName ) { @@ -654,4 +642,3 @@ OUString SAL_CALL FilterDetect::detect( Sequence< PropertyValue >& rMediaDescSeq } // namespace core } // namespace oox - diff --git a/oox/source/core/fragmenthandler.cxx b/oox/source/core/fragmenthandler.cxx index 66c7bf5e136b..a1c42e56c155 100644 --- a/oox/source/core/fragmenthandler.cxx +++ b/oox/source/core/fragmenthandler.cxx @@ -26,22 +26,22 @@ ************************************************************************/ #include "oox/core/fragmenthandler.hxx" -#include "oox/core/xmlfilterbase.hxx" -using ::rtl::OUString; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::io::XInputStream; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::xml::sax::XFastAttributeList; -using ::com::sun::star::xml::sax::XFastContextHandler; -using ::com::sun::star::xml::sax::XLocator; +#include "oox/core/xmlfilterbase.hxx" namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +using ::rtl::OUString; + +// ============================================================================ + FragmentBaseData::FragmentBaseData( XmlFilterBase& rFilter, const OUString& rFragmentPath, RelationsRef xRelations ) : mrFilter( rFilter ), maFragmentPath( rFragmentPath ), @@ -139,4 +139,3 @@ const RecordInfo* FragmentHandler::getRecordInfos() const } // namespace core } // namespace oox - diff --git a/oox/source/core/fragmenthandler2.cxx b/oox/source/core/fragmenthandler2.cxx index 531f43d76d28..e01d2af65113 100644 --- a/oox/source/core/fragmenthandler2.cxx +++ b/oox/source/core/fragmenthandler2.cxx @@ -27,18 +27,18 @@ #include "oox/core/fragmenthandler2.hxx" -using ::rtl::OUString; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::xml::sax::XFastAttributeList; -using ::com::sun::star::xml::sax::XFastContextHandler; - namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +using ::rtl::OUString; + +// ============================================================================ + FragmentHandler2::FragmentHandler2( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEnableTrimSpace ) : FragmentHandler( rFilter, rFragmentPath ), ContextHandler2Helper( bEnableTrimSpace ) @@ -49,11 +49,6 @@ FragmentHandler2::~FragmentHandler2() { } -ContextHandler& FragmentHandler2::queryContextHandler() -{ - return *this; -} - // com.sun.star.xml.sax.XFastDocumentHandler interface -------------------- void SAL_CALL FragmentHandler2::startDocument() throw( SAXException, RuntimeException ) @@ -77,7 +72,7 @@ Reference< XFastContextHandler > SAL_CALL FragmentHandler2::createFastChildConte void SAL_CALL FragmentHandler2::startFastElement( sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw( SAXException, RuntimeException ) { - implStartCurrentContext( nElement, rxAttribs ); + implStartElement( nElement, rxAttribs ); } void SAL_CALL FragmentHandler2::characters( const OUString& rChars ) throw( SAXException, RuntimeException ) @@ -87,7 +82,7 @@ void SAL_CALL FragmentHandler2::characters( const OUString& rChars ) throw( SAXE void SAL_CALL FragmentHandler2::endFastElement( sal_Int32 nElement ) throw( SAXException, RuntimeException ) { - implEndCurrentContext( nElement ); + implEndElement( nElement ); } // oox.core.ContextHandler interface ------------------------------------------ @@ -118,7 +113,11 @@ void FragmentHandler2::onStartElement( const AttributeList& ) { } -void FragmentHandler2::onEndElement( const OUString& ) +void FragmentHandler2::onCharacters( const OUString& ) +{ +} + +void FragmentHandler2::onEndElement() { } @@ -149,4 +148,3 @@ void FragmentHandler2::finalizeImport() } // namespace core } // namespace oox - diff --git a/oox/source/core/recordparser.cxx b/oox/source/core/recordparser.cxx index 8f0de9c2894a..1fea7c85a88b 100644 --- a/oox/source/core/recordparser.cxx +++ b/oox/source/core/recordparser.cxx @@ -26,27 +26,28 @@ ************************************************************************/ #include "oox/core/recordparser.hxx" + #include <vector> #include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/xml/sax/XLocator.hpp> #include <cppuhelper/implbase1.hxx> -#include "oox/helper/recordinputstream.hxx" #include "oox/core/fragmenthandler.hxx" - -using ::rtl::OUString; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::lang::DisposedException; -using ::com::sun::star::io::XInputStream; -using ::com::sun::star::io::IOException; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::xml::sax::XLocator; +#include "oox/helper/recordinputstream.hxx" namespace oox { namespace core { // ============================================================================ +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; + +using ::rtl::OUString; + +// ============================================================================ + namespace prv { class Locator : public ::cppu::WeakImplHelper1< XLocator > @@ -348,4 +349,3 @@ const RecordInfo* RecordParser::getEndRecordInfo( sal_Int32 nRecId ) const } // namespace core } // namespace oox - diff --git a/oox/source/core/relations.cxx b/oox/source/core/relations.cxx index c8d17cce3b9b..db3420906f30 100644 --- a/oox/source/core/relations.cxx +++ b/oox/source/core/relations.cxx @@ -26,17 +26,20 @@ ************************************************************************/ #include "oox/core/relations.hxx" + #include <rtl/ustrbuf.hxx> #include "oox/helper/helper.hxx" -using ::rtl::OUString; -using ::rtl::OUStringBuffer; - namespace oox { namespace core { // ============================================================================ +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +// ============================================================================ + namespace { OUString lclRemoveFileName( const OUString& rPath ) @@ -143,4 +146,3 @@ OUString Relations::getFragmentPathFromFirstType( const OUString& rType ) const } // namespace core } // namespace oox - diff --git a/oox/source/core/relationshandler.cxx b/oox/source/core/relationshandler.cxx index e0d7acda81e0..5ff41b6613f7 100644 --- a/oox/source/core/relationshandler.cxx +++ b/oox/source/core/relationshandler.cxx @@ -26,18 +26,22 @@ ************************************************************************/ #include "oox/core/relationshandler.hxx" + #include <rtl/ustrbuf.hxx> -#include "tokens.hxx" -#include "oox/helper/attributelist.hxx" #include "oox/core/namespaces.hxx" +#include "oox/helper/attributelist.hxx" +#include "tokens.hxx" + +namespace oox { +namespace core { + +// ============================================================================ -using ::rtl::OUString; -using ::rtl::OUStringBuffer; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::xml::sax; -namespace oox { -namespace core { +using ::rtl::OUString; +using ::rtl::OUStringBuffer; // ============================================================================ @@ -106,4 +110,3 @@ Reference< XFastContextHandler > RelationsFragment::createFastChildContext( } // namespace core } // namespace oox - diff --git a/oox/source/core/xmlfilterbase.cxx b/oox/source/core/xmlfilterbase.cxx index 87faadd7a9ce..058efa2e2a7d 100644 --- a/oox/source/core/xmlfilterbase.cxx +++ b/oox/source/core/xmlfilterbase.cxx @@ -28,9 +28,6 @@ #include "oox/core/xmlfilterbase.hxx" #include <cstdio> - -#include <rtl/strbuf.hxx> -#include <rtl/ustrbuf.hxx> #include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/embed/XRelationshipAccess.hpp> #include <com/sun/star/xml/sax/InputSource.hpp> @@ -38,50 +35,41 @@ #include <com/sun/star/document/XDocumentProperties.hpp> #include <comphelper/mediadescriptor.hxx> #include <sax/fshelper.hxx> -#include "properties.hxx" -#include "tokens.hxx" -#include "oox/helper/containerhelper.hxx" -#include "oox/helper/propertyset.hxx" -#include "oox/helper/zipstorage.hxx" +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> #include "oox/core/fasttokenhandler.hxx" #include "oox/core/filterdetect.hxx" #include "oox/core/fragmenthandler.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/recordparser.hxx" #include "oox/core/relationshandler.hxx" +#include "oox/helper/containerhelper.hxx" +#include "oox/helper/propertyset.hxx" +#include "oox/helper/zipstorage.hxx" +#include "properties.hxx" +#include "tokens.hxx" +namespace oox { +namespace core { + +// ============================================================================ + +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::embed; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::xml::sax; + +using ::comphelper::MediaDescriptor; using ::rtl::OStringBuffer; using ::rtl::OUString; using ::rtl::OUStringBuffer; -using ::com::sun::star::beans::StringPair; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Sequence; -using ::com::sun::star::uno::Exception; -using ::com::sun::star::uno::RuntimeException; -using ::com::sun::star::uno::UNO_QUERY; -using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::com::sun::star::uno::UNO_SET_THROW; -using ::com::sun::star::lang::Locale; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::embed::XRelationshipAccess; -using ::com::sun::star::embed::XStorage; -using ::com::sun::star::io::XInputStream; -using ::com::sun::star::io::XOutputStream; -using ::com::sun::star::io::XStream; -using ::com::sun::star::container::XNameContainer; -using ::com::sun::star::xml::sax::XFastParser; -using ::com::sun::star::xml::sax::XFastTokenHandler; -using ::com::sun::star::xml::sax::XFastDocumentHandler; -using ::com::sun::star::xml::sax::InputSource; -using ::com::sun::star::xml::sax::SAXException; -using ::com::sun::star::document::XDocumentProperties; -using ::com::sun::star::util::DateTime; -using ::comphelper::MediaDescriptor; -using ::sax_fastparser::FastSerializerHelper; using ::sax_fastparser::FSHelperPtr; - -namespace oox { -namespace core { +using ::sax_fastparser::FastSerializerHelper; // ============================================================================ @@ -536,4 +524,3 @@ StorageRef XmlFilterBase::implCreateStorage( const Reference< XStream >& rxOutSt } // namespace core } // namespace oox - diff --git a/oox/source/drawingml/chart/chartdrawingfragment.cxx b/oox/source/drawingml/chart/chartdrawingfragment.cxx index dce6535c2f49..5342f3535e51 100644 --- a/oox/source/drawingml/chart/chartdrawingfragment.cxx +++ b/oox/source/drawingml/chart/chartdrawingfragment.cxx @@ -177,7 +177,7 @@ ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, con case CDR_TOKEN( graphicFrame ): if( !mbOleSupport ) return 0; - mxShape.reset( new Shape( "com.sun.star.drawing.OLE2Shape" ) ); + mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ); return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape, true ); case CDR_TOKEN( grpSp ): mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) ); @@ -206,26 +206,24 @@ ContextHandlerRef ChartDrawingFragment::onCreateContext( sal_Int32 nElement, con return 0; } -void ChartDrawingFragment::onEndElement( const OUString& rChars ) +void ChartDrawingFragment::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) - { - case CDR_TOKEN( x ): - case CDR_TOKEN( y ): - if( mxAnchor.get() ) mxAnchor->setPos( getCurrentElement(), getPreviousElement(), rChars ); - break; + if( isCurrentElement( CDR_TOKEN( x ), CDR_TOKEN( y ) ) && mxAnchor.get() ) + mxAnchor->setPos( getCurrentElement(), getParentElement(), rChars ); +} - case CDR_TOKEN( absSizeAnchor ): - case CDR_TOKEN( relSizeAnchor ): - if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() ) - { - Rectangle aLoc = mxAnchor->calcEmuLocation( maEmuChartRect ); - if( (aLoc.X >= 0) && (aLoc.Y >= 0) && (aLoc.Width >= 0) && (aLoc.Height >= 0) ) - mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aLoc ); - } - mxShape.reset(); - mxAnchor.reset(); - break; +void ChartDrawingFragment::onEndElement() +{ + if( isCurrentElement( CDR_TOKEN( absSizeAnchor ), CDR_TOKEN( relSizeAnchor ) ) ) + { + if( mxDrawPage.is() && mxShape.get() && mxAnchor.get() ) + { + Rectangle aLoc = mxAnchor->calcEmuLocation( maEmuChartRect ); + if( (aLoc.X >= 0) && (aLoc.Y >= 0) && (aLoc.Width >= 0) && (aLoc.Height >= 0) ) + mxShape->addShape( getFilter(), getFilter().getCurrentTheme(), mxDrawPage, &aLoc ); + } + mxShape.reset(); + mxAnchor.reset(); } } diff --git a/oox/source/drawingml/chart/datasourcecontext.cxx b/oox/source/drawingml/chart/datasourcecontext.cxx index 6fd12c415a50..a044dd67018d 100644 --- a/oox/source/drawingml/chart/datasourcecontext.cxx +++ b/oox/source/drawingml/chart/datasourcecontext.cxx @@ -90,7 +90,7 @@ ContextHandlerRef DoubleSequenceContext::onCreateContext( sal_Int32 nElement, co return 0; } -void DoubleSequenceContext::onEndElement( const OUString& rChars ) +void DoubleSequenceContext::onCharacters( const OUString& rChars ) { switch( getCurrentElement() ) { @@ -163,7 +163,7 @@ ContextHandlerRef StringSequenceContext::onCreateContext( sal_Int32 nElement, co return 0; } -void StringSequenceContext::onEndElement( const OUString& rChars ) +void StringSequenceContext::onCharacters( const OUString& rChars ) { switch( getCurrentElement() ) { @@ -231,4 +231,3 @@ ContextHandlerRef DataSourceContext::onCreateContext( sal_Int32 nElement, const } // namespace chart } // namespace drawingml } // namespace oox - diff --git a/oox/source/drawingml/chart/seriescontext.cxx b/oox/source/drawingml/chart/seriescontext.cxx index 5412c97f0c91..014ca51e869d 100644 --- a/oox/source/drawingml/chart/seriescontext.cxx +++ b/oox/source/drawingml/chart/seriescontext.cxx @@ -48,8 +48,8 @@ using ::rtl::OUString; namespace { -ContextHandlerRef lclDataLabelSharedCreateContext( - ContextHandler2& rContext, sal_Int32 nElement, const AttributeList& rAttribs, DataLabelModelBase& orModel ) +ContextHandlerRef lclDataLabelSharedCreateContext( ContextHandler2& rContext, + sal_Int32 nElement, const AttributeList& rAttribs, DataLabelModelBase& orModel ) { if( rContext.isRootElement() ) switch( nElement ) { @@ -82,7 +82,7 @@ ContextHandlerRef lclDataLabelSharedCreateContext( orModel.mobShowVal = rAttribs.getBool( XML_val ); return 0; case C_TOKEN( separator ): - // collect separator text in onEndElement() + // collect separator text in onCharacters() return &rContext; case C_TOKEN( spPr ): return new ShapePropertiesContext( rContext, orModel.mxShapeProp.create() ); @@ -92,14 +92,10 @@ ContextHandlerRef lclDataLabelSharedCreateContext( return 0; } -void lclDataLabelSharedEndElement( ContextHandler2& rContext, const OUString& rChars, DataLabelModelBase& orModel ) +void lclDataLabelSharedCharacters( ContextHandler2& rContext, const OUString& rChars, DataLabelModelBase& orModel ) { - switch( rContext.getCurrentElement() ) - { - case C_TOKEN( separator ): - orModel.moaSeparator = rChars; - break; - } + if( rContext.isCurrentElement( C_TOKEN( separator ) ) ) + orModel.moaSeparator = rChars; } } // namespace @@ -130,9 +126,9 @@ ContextHandlerRef DataLabelContext::onCreateContext( sal_Int32 nElement, const A return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel ); } -void DataLabelContext::onEndElement( const OUString& rChars ) +void DataLabelContext::onCharacters( const OUString& rChars ) { - lclDataLabelSharedEndElement( *this, rChars, mrModel ); + lclDataLabelSharedCharacters( *this, rChars, mrModel ); } // ============================================================================ @@ -162,9 +158,9 @@ ContextHandlerRef DataLabelsContext::onCreateContext( sal_Int32 nElement, const return lclDataLabelSharedCreateContext( *this, nElement, rAttribs, mrModel ); } -void DataLabelsContext::onEndElement( const OUString& rChars ) +void DataLabelsContext::onCharacters( const OUString& rChars ) { - lclDataLabelSharedEndElement( *this, rChars, mrModel ); + lclDataLabelSharedCharacters( *this, rChars, mrModel ); } // ============================================================================ @@ -308,7 +304,7 @@ ContextHandlerRef TrendlineContext::onCreateContext( sal_Int32 nElement, const A mrModel.mfIntercept = rAttribs.getDouble( XML_val, 0.0 ); return 0; case C_TOKEN( name ): - return this; // collect name in onEndElement() + return this; // collect name in onCharacters() case C_TOKEN( order ): mrModel.mnOrder = rAttribs.getInteger( XML_val, 2 ); return 0; @@ -326,14 +322,10 @@ ContextHandlerRef TrendlineContext::onCreateContext( sal_Int32 nElement, const A return 0; } -void TrendlineContext::onEndElement( const ::rtl::OUString& rChars ) +void TrendlineContext::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) - { - case C_TOKEN( name ): - mrModel.maName = rChars; - break; - } + if( isCurrentElement( C_TOKEN( name ) ) ) + mrModel.maName = rChars; } // ============================================================================ diff --git a/oox/source/drawingml/chart/titlecontext.cxx b/oox/source/drawingml/chart/titlecontext.cxx index 3954a9d5b08b..cc2b7ace0e72 100644 --- a/oox/source/drawingml/chart/titlecontext.cxx +++ b/oox/source/drawingml/chart/titlecontext.cxx @@ -55,34 +55,28 @@ TextContext::~TextContext() ContextHandlerRef TextContext::onCreateContext( sal_Int32 nElement, const AttributeList& ) { - switch( getCurrentElement() ) + // this context handler is used for <c:tx> and embedded <c:v> elements + if( isCurrentElement( C_TOKEN( tx ) ) ) switch( nElement ) { - case C_TOKEN( tx ): - switch( nElement ) - { - case C_TOKEN( rich ): - return new TextBodyContext( *this, mrModel.mxTextBody.create() ); - case C_TOKEN( strRef ): - OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" ); - return new StringSequenceContext( *this, mrModel.mxDataSeq.create() ); - case C_TOKEN( v ): - OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" ); - return this; // collect value in onEndElement() - } - break; + case C_TOKEN( rich ): + return new TextBodyContext( *this, mrModel.mxTextBody.create() ); + + case C_TOKEN( strRef ): + OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" ); + return new StringSequenceContext( *this, mrModel.mxDataSeq.create() ); + + case C_TOKEN( v ): + OSL_ENSURE( !mrModel.mxDataSeq, "TextContext::onCreateContext - multiple data sequences" ); + return this; // collect value in onCharacters() } - return false; + return 0; } -void TextContext::onEndElement( const OUString& rChars ) +void TextContext::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) - { - case C_TOKEN( v ): - // store as single string sequence element - mrModel.mxDataSeq.create().maData[ 0 ] <<= rChars; - break; - } + // store as single string sequence element + if( isCurrentElement( C_TOKEN( v ) ) ) + mrModel.mxDataSeq.create().maData[ 0 ] <<= rChars; } // ============================================================================ @@ -98,25 +92,25 @@ TitleContext::~TitleContext() ContextHandlerRef TitleContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { - switch( getCurrentElement() ) + // this context handler is used for <c:title> only + switch( nElement ) { - case C_TOKEN( title ): - switch( nElement ) - { - case C_TOKEN( layout ): - return new LayoutContext( *this, mrModel.mxLayout.create() ); - case C_TOKEN( overlay ): - // default is 'false', not 'true' as specified - mrModel.mbOverlay = rAttribs.getBool( XML_val, false ); - return 0; - case C_TOKEN( spPr ): - return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() ); - case C_TOKEN( tx ): - return new TextContext( *this, mrModel.mxText.create() ); - case C_TOKEN( txPr ): - return new TextBodyContext( *this, mrModel.mxTextProp.create() ); - } - break; + case C_TOKEN( layout ): + return new LayoutContext( *this, mrModel.mxLayout.create() ); + + case C_TOKEN( overlay ): + // default is 'false', not 'true' as specified + mrModel.mbOverlay = rAttribs.getBool( XML_val, false ); + return 0; + + case C_TOKEN( spPr ): + return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() ); + + case C_TOKEN( tx ): + return new TextContext( *this, mrModel.mxText.create() ); + + case C_TOKEN( txPr ): + return new TextBodyContext( *this, mrModel.mxTextProp.create() ); } return 0; } @@ -134,26 +128,26 @@ LegendContext::~LegendContext() ContextHandlerRef LegendContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { - switch( getCurrentElement() ) + // this context handler is used for <c:legend> only + switch( nElement ) { - case C_TOKEN( legend ): - switch( nElement ) - { - case C_TOKEN( layout ): - return new LayoutContext( *this, mrModel.mxLayout.create() ); - case C_TOKEN( legendPos ): - mrModel.mnPosition = rAttribs.getToken( XML_val, XML_r ); - return 0; - case C_TOKEN( overlay ): - // default is 'false', not 'true' as specified - mrModel.mbOverlay = rAttribs.getBool( XML_val, false ); - return 0; - case C_TOKEN( spPr ): - return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() ); - case C_TOKEN( txPr ): - return new TextBodyContext( *this, mrModel.mxTextProp.create() ); - } - break; + case C_TOKEN( layout ): + return new LayoutContext( *this, mrModel.mxLayout.create() ); + + case C_TOKEN( legendPos ): + mrModel.mnPosition = rAttribs.getToken( XML_val, XML_r ); + return 0; + + case C_TOKEN( overlay ): + // default is 'false', not 'true' as specified + mrModel.mbOverlay = rAttribs.getBool( XML_val, false ); + return 0; + + case C_TOKEN( spPr ): + return new ShapePropertiesContext( *this, mrModel.mxShapeProp.create() ); + + case C_TOKEN( txPr ): + return new TextBodyContext( *this, mrModel.mxTextProp.create() ); } return 0; } diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx index 48461bb2858e..0df33903ffbb 100644 --- a/oox/source/drawingml/graphicshapecontext.cxx +++ b/oox/source/drawingml/graphicshapecontext.cxx @@ -27,7 +27,6 @@ #include "oox/drawingml/graphicshapecontext.hxx" #include <osl/diagnose.h> -#include <com/sun/star/chart2/XChartDocument.hpp> #include "oox/drawingml/fillpropertiesgroupcontext.hxx" #include "oox/drawingml/customshapeproperties.hxx" @@ -41,12 +40,8 @@ #include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmlshape.hxx" #include "oox/vml/vmlshapecontainer.hxx" -#include "oox/ole/oleobjecthelper.hxx" #include "oox/drawingml/fillproperties.hxx" #include "oox/drawingml/transform2dcontext.hxx" -#include "oox/drawingml/chart/chartconverter.hxx" -#include "oox/drawingml/chart/chartspacefragment.hxx" -#include "oox/drawingml/chart/chartspacemodel.hxx" #include "properties.hxx" #include "tokens.hxx" @@ -58,7 +53,6 @@ using namespace ::com::sun::star::lang; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::xml::sax; using namespace ::oox::core; -using ::oox::vml::OleObjectInfo; namespace oox { namespace drawingml { @@ -157,65 +151,19 @@ Reference< XFastContextHandler > GraphicalObjectFrameContext::createFastChildCon // ============================================================================ -class CreateOleObjectCallback : public CreateShapeCallback -{ -public: - explicit CreateOleObjectCallback( XmlFilterBase& rFilter, const ::boost::shared_ptr< OleObjectInfo >& rxOleObjectInfo ); - virtual OUString onCreateXShape( const OUString& rServiceName, const awt::Rectangle& rShapeRect ); - -private: - ::boost::shared_ptr< OleObjectInfo > mxOleObjectInfo; -}; - -// ---------------------------------------------------------------------------- - -CreateOleObjectCallback::CreateOleObjectCallback( XmlFilterBase& rFilter, const ::boost::shared_ptr< OleObjectInfo >& rxOleObjectInfo ) : - CreateShapeCallback( rFilter ), - mxOleObjectInfo( rxOleObjectInfo ) -{ -} - -OUString CreateOleObjectCallback::onCreateXShape( const OUString&, const awt::Rectangle& rShapeRect ) -{ - awt::Size aOleSize( rShapeRect.Width, rShapeRect.Height ); - bool bSuccess = mrFilter.getOleObjectHelper().importOleObject( maShapeProps, *mxOleObjectInfo, aOleSize ); - OUString aServiceName = bSuccess ? CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ) : CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ); - - // get the path to the representation graphic - OUString aGraphicPath; - if( mxOleObjectInfo->maShapeId.getLength() > 0 ) - if( ::oox::vml::Drawing* pVmlDrawing = mrFilter.getVmlDrawing() ) - if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) ) - aGraphicPath = pVmlShape->getGraphicPath(); - - // import and store the graphic - if( aGraphicPath.getLength() > 0 ) - { - Reference< graphic::XGraphic > xGraphic = mrFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath ); - if( xGraphic.is() ) - maShapeProps[ PROP_Graphic ] <<= xGraphic; - } - - return aServiceName; -} - -// ============================================================================ - OleObjectGraphicDataContext::OleObjectGraphicDataContext( ContextHandler& rParent, ShapePtr xShape ) : ShapeContext( rParent, ShapePtr(), xShape ), - mxOleObjectInfo( new OleObjectInfo( true ) ) + mrOleObjectInfo( xShape->setOleObjectType() ) { - CreateShapeCallbackRef xCallback( new CreateOleObjectCallback( getFilter(), mxOleObjectInfo ) ); - xShape->setCreateShapeCallback( xCallback ); } OleObjectGraphicDataContext::~OleObjectGraphicDataContext() { /* Register the OLE shape at the VML drawing, this prevents that the related VML shape converts the OLE object by itself. */ - if( mxOleObjectInfo->maShapeId.getLength() > 0 ) + if( mrOleObjectInfo.maShapeId.getLength() > 0 ) if( ::oox::vml::Drawing* pVmlDrawing = getFilter().getVmlDrawing() ) - pVmlDrawing->registerOleObject( *mxOleObjectInfo ); + pVmlDrawing->registerOleObject( mrOleObjectInfo ); } Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildContext( sal_Int32 nElement, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException) @@ -227,37 +175,37 @@ Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildCon { case PPT_TOKEN( oleObj ): { - mxOleObjectInfo->maShapeId = aAttribs.getXString( XML_spid, OUString() ); + mrOleObjectInfo.maShapeId = aAttribs.getXString( XML_spid, OUString() ); const Relation* pRelation = getRelations().getRelationFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) ); OSL_ENSURE( pRelation, "OleObjectGraphicDataContext::createFastChildContext - missing relation for OLE object" ); if( pRelation ) { - mxOleObjectInfo->mbLinked = pRelation->mbExternal; + mrOleObjectInfo.mbLinked = pRelation->mbExternal; if( pRelation->mbExternal ) { - mxOleObjectInfo->maTargetLink = getFilter().getAbsoluteUrl( pRelation->maTarget ); + mrOleObjectInfo.maTargetLink = getFilter().getAbsoluteUrl( pRelation->maTarget ); } else { OUString aFragmentPath = getFragmentPathFromRelation( *pRelation ); if( aFragmentPath.getLength() > 0 ) - getFilter().importBinaryData( mxOleObjectInfo->maEmbeddedData, aFragmentPath ); + getFilter().importBinaryData( mrOleObjectInfo.maEmbeddedData, aFragmentPath ); } } - mxOleObjectInfo->maName = aAttribs.getXString( XML_name, OUString() ); - mxOleObjectInfo->maProgId = aAttribs.getXString( XML_progId, OUString() ); - mxOleObjectInfo->mbShowAsIcon = aAttribs.getBool( XML_showAsIcon, false ); + mrOleObjectInfo.maName = aAttribs.getXString( XML_name, OUString() ); + mrOleObjectInfo.maProgId = aAttribs.getXString( XML_progId, OUString() ); + mrOleObjectInfo.mbShowAsIcon = aAttribs.getBool( XML_showAsIcon, false ); xRet.set( this ); } break; case PPT_TOKEN( embed ): - OSL_ENSURE( !mxOleObjectInfo->mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" ); + OSL_ENSURE( !mrOleObjectInfo.mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" ); break; case PPT_TOKEN( link ): - OSL_ENSURE( mxOleObjectInfo->mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" ); - mxOleObjectInfo->mbAutoUpdate = aAttribs.getBool( XML_updateAutomatic, false ); + OSL_ENSURE( mrOleObjectInfo.mbLinked, "OleObjectGraphicDataContext::createFastChildContext - unexpected child element" ); + mrOleObjectInfo.mbAutoUpdate = aAttribs.getBool( XML_updateAutomatic, false ); break; } return xRet; @@ -268,8 +216,7 @@ Reference< XFastContextHandler > OleObjectGraphicDataContext::createFastChildCon DiagramGraphicDataContext::DiagramGraphicDataContext( ContextHandler& rParent, ShapePtr pShapePtr ) : ShapeContext( rParent, ShapePtr(), pShapePtr ) { - pShapePtr->setServiceName( "com.sun.star.drawing.GroupShape" ); - pShapePtr->setSubType( 0 ); + pShapePtr->setDiagramType(); } DiagramGraphicDataContext::~DiagramGraphicDataContext() @@ -349,62 +296,10 @@ Reference< XFastContextHandler > DiagramGraphicDataContext::createFastChildConte // ============================================================================ -class CreateChartCallback : public CreateShapeCallback -{ -public: - explicit CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEmbedShapes ); - virtual void onXShapeCreated( const Reference< drawing::XShape >& rxShape, const Reference< drawing::XShapes >& rxShapes ) const; - -private: - OUString maFragmentPath; - bool mbEmbedShapes; -}; - -// ---------------------------------------------------------------------------- - -CreateChartCallback::CreateChartCallback( XmlFilterBase& rFilter, const OUString& rFragmentPath, bool bEmbedShapes ) : - CreateShapeCallback( rFilter ), - maFragmentPath( rFragmentPath ), - mbEmbedShapes( bEmbedShapes ) -{ -} - -void CreateChartCallback::onXShapeCreated( const Reference< drawing::XShape >& rxShape, const Reference< drawing::XShapes >& rxShapes ) const -{ - OSL_ENSURE( maFragmentPath.getLength() > 0, "CreateChartCallback::onXShapeCreated - missing chart fragment" ); - if( maFragmentPath.getLength() > 0 ) try - { - // set the chart2 OLE class ID at the OLE shape - PropertySet aShapeProp( rxShape ); - aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) ); - - // get the XModel interface of the embedded object from the OLE shape - Reference< frame::XModel > xDocModel; - aShapeProp.getProperty( xDocModel, PROP_Model ); - Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW ); - - // load the chart data from the XML fragment - chart::ChartSpaceModel aModel; - mrFilter.importFragment( new chart::ChartSpaceFragment( mrFilter, maFragmentPath, aModel ) ); - - // convert imported chart model to chart document - Reference< drawing::XShapes > xExternalPage; - if( !mbEmbedShapes ) - xExternalPage = rxShapes; - mrFilter.getChartConverter().convertFromModel( mrFilter, aModel, xChartDoc, xExternalPage, rxShape->getPosition(), rxShape->getSize() ); - } - catch( Exception& ) - { - } -} - -// ============================================================================ - ChartGraphicDataContext::ChartGraphicDataContext( ContextHandler& rParent, const ShapePtr& rxShape, bool bEmbedShapes ) : ShapeContext( rParent, ShapePtr(), rxShape ), - mbEmbedShapes( bEmbedShapes ) + mrChartShapeInfo( rxShape->setChartType( bEmbedShapes ) ) { - rxShape->setServiceName( "com.sun.star.drawing.OLE2Shape" ); } Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext( ::sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) @@ -413,9 +308,7 @@ Reference< XFastContextHandler > ChartGraphicDataContext::createFastChildContext if( nElement == C_TOKEN( chart ) ) { AttributeList aAttribs( rxAttribs ); - OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) ); - CreateShapeCallbackRef xCallback( new CreateChartCallback( getFilter(), aFragmentPath, mbEmbedShapes ) ); - mpShapePtr->setCreateShapeCallback( xCallback ); + mrChartShapeInfo.maFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( id ), OUString() ) ); } return 0; } diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index f0ae2ec2a7a3..d3a6afb0d4ad 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -32,8 +32,15 @@ #include "oox/drawingml/lineproperties.hxx" #include "oox/drawingml/textbody.hxx" #include "oox/drawingml/table/tableproperties.hxx" +#include "oox/drawingml/chart/chartconverter.hxx" +#include "oox/drawingml/chart/chartspacefragment.hxx" +#include "oox/drawingml/chart/chartspacemodel.hxx" +#include "oox/vml/vmldrawing.hxx" +#include "oox/vml/vmlshape.hxx" +#include "oox/vml/vmlshapecontainer.hxx" #include "oox/core/namespaces.hxx" #include "oox/core/xmlfilterbase.hxx" +#include "oox/helper/graphichelper.hxx" #include "oox/helper/propertyset.hxx" #include "properties.hxx" #include "tokens.hxx" @@ -45,6 +52,7 @@ #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/drawing/HomogenMatrix3.hpp> #include <com/sun/star/text/XText.hpp> +#include <com/sun/star/chart2/XChartDocument.hpp> #include <basegfx/point/b2dpoint.hxx> #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/matrix/b2dhommatrix.hxx> @@ -64,26 +72,6 @@ namespace oox { namespace drawingml { // ============================================================================ -CreateShapeCallback::CreateShapeCallback( XmlFilterBase& rFilter ) : - mrFilter( rFilter ) -{ -} - -CreateShapeCallback::~CreateShapeCallback() -{ -} - -OUString CreateShapeCallback::onCreateXShape( const OUString& rServiceName, const Rectangle& ) -{ - return rServiceName; -} - -void CreateShapeCallback::onXShapeCreated( const Reference< XShape >&, const Reference< XShapes >& ) const -{ -} - -// ============================================================================ - Shape::Shape( const sal_Char* pServiceName ) : mpLinePropertiesPtr( new LineProperties ) , mpFillPropertiesPtr( new FillProperties ) @@ -92,6 +80,7 @@ Shape::Shape( const sal_Char* pServiceName ) , mpMasterTextListStyle( new TextListStyle ) , mnSubType( 0 ) , mnSubTypeIndex( -1 ) +, meFrameType( FRAMETYPE_GENERIC ) , mnRotation( 0 ) , mbFlipH( false ) , mbFlipV( false ) @@ -101,6 +90,7 @@ Shape::Shape( const sal_Char* pServiceName ) msServiceName = OUString::createFromAscii( pServiceName ); setDefaults(); } + Shape::~Shape() { } @@ -123,6 +113,39 @@ void Shape::setDefaults() maShapeProperties[ PROP_CharHeight ] <<= static_cast< float >( 18.0 ); } +::oox::vml::OleObjectInfo& Shape::setOleObjectType() +{ + OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setOleObjectType - multiple frame types" ); + meFrameType = FRAMETYPE_OLEOBJECT; + mxOleObjectInfo.reset( new ::oox::vml::OleObjectInfo( true ) ); + return *mxOleObjectInfo; +} + +ChartShapeInfo& Shape::setChartType( bool bEmbedShapes ) +{ + OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setChartType - multiple frame types" ); + meFrameType = FRAMETYPE_CHART; + msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Object" ); + mxChartShapeInfo.reset( new ChartShapeInfo( bEmbedShapes ) ); + return *mxChartShapeInfo; +} + +void Shape::setDiagramType() +{ + OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setDiagramType - multiple frame types" ); + meFrameType = FRAMETYPE_DIAGRAM; + msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ); + mnSubType = 0; +} + +void Shape::setTableType() +{ + OSL_ENSURE( meFrameType == FRAMETYPE_GENERIC, "Shape::setTableType - multiple frame types" ); + meFrameType = FRAMETYPE_TABLE; + msServiceName = CREATE_OUSTRING( "com.sun.star.drawing.TableShape" ); + mnSubType = 0; +} + void Shape::setServiceName( const sal_Char* pServiceName ) { if ( pServiceName ) @@ -137,7 +160,7 @@ const ShapeStyleRef* Shape::getShapeStyleRef( sal_Int32 nRefType ) const } void Shape::addShape( - const ::oox::core::XmlFilterBase& rFilterBase, + ::oox::core::XmlFilterBase& rFilterBase, const Theme* pTheme, const Reference< XShapes >& rxShapes, const awt::Rectangle* pShapeRect, @@ -189,7 +212,7 @@ void Shape::applyShapeReference( const Shape& rReferencedShape ) // for group shapes, the following method is also adding each child void Shape::addChildren( - const ::oox::core::XmlFilterBase& rFilterBase, + XmlFilterBase& rFilterBase, Shape& rMaster, const Theme* pTheme, const Reference< XShapes >& rxShapes, @@ -247,7 +270,7 @@ void Shape::addChildren( } Reference< XShape > Shape::createAndInsert( - const ::oox::core::XmlFilterBase& rFilterBase, + ::oox::core::XmlFilterBase& rFilterBase, const rtl::OUString& rServiceName, const Theme* pTheme, const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes, @@ -256,11 +279,10 @@ Reference< XShape > Shape::createAndInsert( { awt::Size aSize( pShapeRect ? awt::Size( pShapeRect->Width, pShapeRect->Height ) : maSize ); awt::Point aPosition( pShapeRect ? awt::Point( pShapeRect->X, pShapeRect->Y ) : maPosition ); + awt::Rectangle aShapeRectHmm( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 ); - OUString aServiceName = rServiceName; - if( mxCreateCallback.get() ) - aServiceName = mxCreateCallback->onCreateXShape( aServiceName, awt::Rectangle( aPosition.X / 360, aPosition.Y / 360, aSize.Width / 360, aSize.Height / 360 ) ); - sal_Bool bIsCustomShape = aServiceName == OUString::createFromAscii( "com.sun.star.drawing.CustomShape" ); + OUString aServiceName = finalizeServiceName( rFilterBase, rServiceName, aShapeRectHmm ); + sal_Bool bIsCustomShape = aServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "com.sun.star.drawing.CustomShape" ) ); basegfx::B2DHomMatrix aTransformation; if( aSize.Width != 1 || aSize.Height != 1) @@ -432,13 +454,6 @@ Reference< XShape > Shape::createAndInsert( PropertyMap aShapeProperties; PropertyMap::const_iterator aShapePropIter; - if( mxCreateCallback.get() ) - { - for ( aShapePropIter = mxCreateCallback->getShapeProperties().begin(); - aShapePropIter != mxCreateCallback->getShapeProperties().end(); aShapePropIter++ ) - aShapeProperties[ (*aShapePropIter).first ] = (*aShapePropIter).second; - } - // add properties from textbody to shape properties if( mpTextBody.get() ) { @@ -502,9 +517,8 @@ Reference< XShape > Shape::createAndInsert( xLockable->removeActionLock(); } - // use a callback for further processing on the XShape (e.g. charts) - if( mxShape.is() && mxCreateCallback.get() ) - mxCreateCallback->onXShapeCreated( mxShape, rxShapes ); + if( mxShape.is() ) + finalizeXShape( rFilterBase, rxShapes ); return mxShape; } @@ -537,5 +551,77 @@ void Shape::setMasterTextListStyle( const TextListStylePtr& pMasterTextListStyle mpMasterTextListStyle = pMasterTextListStyle; } +OUString Shape::finalizeServiceName( XmlFilterBase& rFilter, const OUString& rServiceName, const Rectangle& rShapeRect ) +{ + OUString aServiceName = rServiceName; + switch( meFrameType ) + { + case FRAMETYPE_OLEOBJECT: + { + Size aOleSize( rShapeRect.Width, rShapeRect.Height ); + if( rFilter.getOleObjectHelper().importOleObject( maShapeProperties, *mxOleObjectInfo, aOleSize ) ) + aServiceName = CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ); + + // get the path to the representation graphic + OUString aGraphicPath; + if( mxOleObjectInfo->maShapeId.getLength() > 0 ) + if( ::oox::vml::Drawing* pVmlDrawing = rFilter.getVmlDrawing() ) + if( const ::oox::vml::ShapeBase* pVmlShape = pVmlDrawing->getShapes().getShapeById( mxOleObjectInfo->maShapeId, true ) ) + aGraphicPath = pVmlShape->getGraphicPath(); + + // import and store the graphic + if( aGraphicPath.getLength() > 0 ) + { + Reference< graphic::XGraphic > xGraphic = rFilter.getGraphicHelper().importEmbeddedGraphic( aGraphicPath ); + if( xGraphic.is() ) + maShapeProperties[ PROP_Graphic ] <<= xGraphic; + } + } + break; + + default:; + } + return aServiceName; +} + +void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes ) +{ + switch( meFrameType ) + { + case FRAMETYPE_CHART: + { + OSL_ENSURE( mxChartShapeInfo->maFragmentPath.getLength() > 0, "Shape::finalizeXShape - missing chart fragment" ); + if( mxShape.is() && (mxChartShapeInfo->maFragmentPath.getLength() > 0) ) try + { + // set the chart2 OLE class ID at the OLE shape + PropertySet aShapeProp( mxShape ); + aShapeProp.setProperty( PROP_CLSID, CREATE_OUSTRING( "12dcae26-281f-416f-a234-c3086127382e" ) ); + + // get the XModel interface of the embedded object from the OLE shape + Reference< frame::XModel > xDocModel; + aShapeProp.getProperty( xDocModel, PROP_Model ); + Reference< chart2::XChartDocument > xChartDoc( xDocModel, UNO_QUERY_THROW ); + + // load the chart data from the XML fragment + chart::ChartSpaceModel aModel; + rFilter.importFragment( new chart::ChartSpaceFragment( rFilter, mxChartShapeInfo->maFragmentPath, aModel ) ); + + // convert imported chart model to chart document + Reference< drawing::XShapes > xExternalPage; + if( !mxChartShapeInfo->mbEmbedShapes ) + xExternalPage = rxShapes; + rFilter.getChartConverter().convertFromModel( rFilter, aModel, xChartDoc, xExternalPage, mxShape->getPosition(), mxShape->getSize() ); + } + catch( Exception& ) + { + } + } + break; + + default:; + } +} + +// ============================================================================ } } diff --git a/oox/source/drawingml/shapegroupcontext.cxx b/oox/source/drawingml/shapegroupcontext.cxx index e1bd51f852ad..2c8e0808d8af 100644 --- a/oox/source/drawingml/shapegroupcontext.cxx +++ b/oox/source/drawingml/shapegroupcontext.cxx @@ -108,7 +108,7 @@ Reference< XFastContextHandler > ShapeGroupContext::createFastChildContext( sal_ xRet.set( new GraphicShapeContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ) ) ); break; case XML_graphicFrame: // CT_GraphicalObjectFrame - xRet.set( new GraphicalObjectFrameContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.OLE2Shape" ) ), true ) ); + xRet.set( new GraphicalObjectFrameContext( *this, mpGroupShapePtr, ShapePtr( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ), true ) ); break; } if( !xRet.is() ) diff --git a/oox/source/drawingml/table/tablecontext.cxx b/oox/source/drawingml/table/tablecontext.cxx index b194fdc9ee26..ef5d87e3081b 100644 --- a/oox/source/drawingml/table/tablecontext.cxx +++ b/oox/source/drawingml/table/tablecontext.cxx @@ -44,8 +44,7 @@ TableContext::TableContext( ContextHandler& rParent, ShapePtr pShapePtr ) : ShapeContext( rParent, ShapePtr(), pShapePtr ) , mrTableProperties( *pShapePtr->getTableProperties().get() ) { - pShapePtr->setServiceName( "com.sun.star.drawing.TableShape" ); - pShapePtr->setSubType( 0 ); + pShapePtr->setTableType(); } TableContext::~TableContext() diff --git a/oox/source/helper/attributelist.cxx b/oox/source/helper/attributelist.cxx index 1f365a1fdacd..ae10c290b425 100644 --- a/oox/source/helper/attributelist.cxx +++ b/oox/source/helper/attributelist.cxx @@ -29,6 +29,7 @@ #include <osl/diagnose.h> #include <rtl/ustrbuf.hxx> +#include "oox/token/tokenmap.hxx" namespace oox { @@ -77,6 +78,11 @@ sal_Unicode lclGetXChar( const sal_Unicode*& rpcStr, const sal_Unicode* pcEnd ) // ---------------------------------------------------------------------------- +sal_Int32 AttributeConversion::decodeToken( const OUString& rValue ) +{ + return StaticTokenMap::get().getTokenFromUnicode( rValue ); +} + OUString AttributeConversion::decodeXString( const OUString& rValue ) { // string shorter than one encoded character - no need to decode diff --git a/oox/source/ole/axbinaryreader.cxx b/oox/source/ole/axbinaryreader.cxx index 68a18932bf42..0c4743be9e31 100755 --- a/oox/source/ole/axbinaryreader.cxx +++ b/oox/source/ole/axbinaryreader.cxx @@ -93,7 +93,8 @@ AxFontData::AxFontData() : mnFontEffects( 0 ), mnFontHeight( 160 ), mnFontCharSet( WINDOWS_CHARSET_DEFAULT ), - mnHorAlign( AX_FONTDATA_LEFT ) + mnHorAlign( AX_FONTDATA_LEFT ), + mbDblUnderline( false ) { } @@ -121,6 +122,7 @@ bool AxFontData::importBinaryModel( BinaryInputStream& rInStrm ) aReader.skipIntProperty< sal_uInt8 >(); // font pitch/family aReader.readIntProperty< sal_uInt8 >( mnHorAlign ); aReader.skipIntProperty< sal_uInt16 >(); // font weight + mbDblUnderline = false; return aReader.finalizeImport(); } @@ -135,6 +137,7 @@ bool AxFontData::importStdFont( BinaryInputStream& rInStrm ) setFlag( mnFontEffects, AX_FONTDATA_ITALIC, getFlag( aFontInfo.mnFlags, OLE_STDFONT_ITALIC ) ); setFlag( mnFontEffects, AX_FONTDATA_UNDERLINE, getFlag( aFontInfo.mnFlags, OLE_STDFONT_UNDERLINE ) ); setFlag( mnFontEffects, AX_FONTDATA_STRIKEOUT, getFlag( aFontInfo.mnFlags,OLE_STDFONT_STRIKE ) ); + mbDblUnderline = false; // StdFont stores font height in 1/10,000 of points setHeightPoints( getLimitedValue< sal_Int16, sal_Int32 >( aFontInfo.mnHeight / 10000, 0, SAL_MAX_INT16 ) ); mnFontCharSet = aFontInfo.mnCharSet; @@ -147,7 +150,7 @@ bool AxFontData::importStdFont( BinaryInputStream& rInStrm ) bool AxFontData::importGuidAndFont( BinaryInputStream& rInStrm ) { OUString aGuid = OleHelper::importGuid( rInStrm ); - if( aGuid.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "{AFC20920-DA4E-11CE-B943-00AA006887B4}" ) ) ) + if( aGuid.equalsAscii( AX_GUID_CFONT ) ) return importBinaryModel( rInStrm ); if( aGuid.equalsAscii( OLE_GUID_STDFONT ) ) return importStdFont( rInStrm ); diff --git a/oox/source/ole/axcontrol.cxx b/oox/source/ole/axcontrol.cxx index 73da2edea7d1..a0d3d7340f57 100644 --- a/oox/source/ole/axcontrol.cxx +++ b/oox/source/ole/axcontrol.cxx @@ -76,6 +76,7 @@ using namespace ::com::sun::star::form::binding; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::style; using namespace ::com::sun::star::table; using namespace ::com::sun::star::uno; @@ -108,28 +109,6 @@ const sal_uInt32 COMCTL_ID_PROGRESSBAR_60 = 0x97AB8A01; // ---------------------------------------------------------------------------- -const sal_uInt32 AX_FLAGS_ENABLED = 0x00000002; -const sal_uInt32 AX_FLAGS_LOCKED = 0x00000004; -const sal_uInt32 AX_FLAGS_OPAQUE = 0x00000008; -const sal_uInt32 AX_FLAGS_COLUMNHEADS = 0x00000400; -const sal_uInt32 AX_FLAGS_ENTIREROWS = 0x00000800; -const sal_uInt32 AX_FLAGS_EXISTINGENTRIES = 0x00001000; -const sal_uInt32 AX_FLAGS_CAPTIONLEFT = 0x00002000; -const sal_uInt32 AX_FLAGS_EDITABLE = 0x00004000; -const sal_uInt32 AX_FLAGS_IMEMODE_MASK = 0x00078000; -const sal_uInt32 AX_FLAGS_DRAGENABLED = 0x00080000; -const sal_uInt32 AX_FLAGS_ENTERASNEWLINE = 0x00100000; -const sal_uInt32 AX_FLAGS_KEEPSELECTION = 0x00200000; -const sal_uInt32 AX_FLAGS_TABASCHARACTER = 0x00400000; -const sal_uInt32 AX_FLAGS_WORDWRAP = 0x00800000; -const sal_uInt32 AX_FLAGS_BORDERSSUPPRESSED = 0x02000000; -const sal_uInt32 AX_FLAGS_SELECTLINE = 0x04000000; -const sal_uInt32 AX_FLAGS_SINGLECHARSELECT = 0x08000000; -const sal_uInt32 AX_FLAGS_AUTOSIZE = 0x10000000; -const sal_uInt32 AX_FLAGS_HIDESELECTION = 0x20000000; -const sal_uInt32 AX_FLAGS_MAXLENAUTOTAB = 0x40000000; -const sal_uInt32 AX_FLAGS_MULTILINE = 0x80000000; - const sal_uInt32 AX_CMDBUTTON_DEFFLAGS = 0x0000001B; const sal_uInt32 AX_LABEL_DEFFLAGS = 0x0080001B; const sal_uInt32 AX_IMAGE_DEFFLAGS = 0x0000001B; @@ -164,30 +143,10 @@ const sal_uInt32 AX_PICPOS_BELOWRIGHT = AX_PICPOS_IMPL( TOPRIGHT, BOTTO const sal_uInt32 AX_PICPOS_CENTER = AX_PICPOS_IMPL( CENTER, CENTER ); #undef AX_PICPOS_IMPL -const sal_Int32 AX_DISPLAYSTYLE_TEXT = 1; -const sal_Int32 AX_DISPLAYSTYLE_LISTBOX = 2; -const sal_Int32 AX_DISPLAYSTYLE_COMBOBOX = 3; -const sal_Int32 AX_DISPLAYSTYLE_CHECKBOX = 4; -const sal_Int32 AX_DISPLAYSTYLE_OPTBUTTON = 5; -const sal_Int32 AX_DISPLAYSTYLE_TOGGLE = 6; -const sal_Int32 AX_DISPLAYSTYLE_DROPDOWN = 7; - -const sal_Int32 AX_SELCTION_SINGLE = 0; -const sal_Int32 AX_SELCTION_MULTI = 1; -const sal_Int32 AX_SELCTION_EXTENDED = 2; - -const sal_Int32 AX_SCROLLBAR_NONE = 0x00; -const sal_Int32 AX_SCROLLBAR_HORIZONTAL = 0x01; -const sal_Int32 AX_SCROLLBAR_VERTICAL = 0x02; - const sal_Int32 AX_MATCHENTRY_FIRSTLETTER = 0; const sal_Int32 AX_MATCHENTRY_COMPLETE = 1; const sal_Int32 AX_MATCHENTRY_NONE = 2; -const sal_Int32 AX_SHOWDROPBUTTON_NEVER = 0; -const sal_Int32 AX_SHOWDROPBUTTON_FOCUS = 1; -const sal_Int32 AX_SHOWDROPBUTTON_ALWAYS = 2; - const sal_Int32 AX_ORIENTATION_AUTO = -1; const sal_Int32 AX_ORIENTATION_VERTICAL = 0; const sal_Int32 AX_ORIENTATION_HORIZONTAL = 1; @@ -333,11 +292,22 @@ void ControlConverter::convertPicture( PropertyMap& rPropMap, const StreamDataSe void ControlConverter::convertOrientation( PropertyMap& rPropMap, bool bHorizontal ) const { - namespace AwtScrollBarOrient = ::com::sun::star::awt::ScrollBarOrientation; - sal_Int32 nScrollOrient = bHorizontal ? AwtScrollBarOrient::HORIZONTAL : AwtScrollBarOrient::VERTICAL; + sal_Int32 nScrollOrient = bHorizontal ? ScrollBarOrientation::HORIZONTAL : ScrollBarOrientation::VERTICAL; rPropMap.setProperty( PROP_Orientation, nScrollOrient ); } +void ControlConverter::convertVerticalAlign( PropertyMap& rPropMap, sal_Int32 nVerticalAlign ) const +{ + VerticalAlignment eAlign = VerticalAlignment_TOP; + switch( nVerticalAlign ) + { + case XML_Top: eAlign = VerticalAlignment_TOP; break; + case XML_Center: eAlign = VerticalAlignment_MIDDLE; break; + case XML_Bottom: eAlign = VerticalAlignment_BOTTOM; break; + } + rPropMap.setProperty( PROP_VerticalAlign, eAlign ); +} + void ControlConverter::convertScrollBar( PropertyMap& rPropMap, sal_Int32 nMin, sal_Int32 nMax, sal_Int32 nPosition, sal_Int32 nSmallChange, sal_Int32 nLargeChange, bool bAwtModel ) const @@ -451,8 +421,7 @@ void ControlConverter::convertAxBorder( PropertyMap& rPropMap, void ControlConverter::convertAxVisualEffect( PropertyMap& rPropMap, sal_Int32 nSpecialEffect ) const { - namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect; - sal_Int16 nVisualEffect = (nSpecialEffect == AX_SPECIALEFFECT_FLAT) ? AwtVisualEffect::FLAT : AwtVisualEffect::LOOK3D; + sal_Int16 nVisualEffect = (nSpecialEffect == AX_SPECIALEFFECT_FLAT) ? VisualEffect::FLAT : VisualEffect::LOOK3D; rPropMap.setProperty( PROP_VisualEffect, nVisualEffect ); } @@ -462,23 +431,22 @@ void ControlConverter::convertAxPicture( PropertyMap& rPropMap, const StreamData convertPicture( rPropMap, rPicData ); // picture position - namespace AwtImagePos = ::com::sun::star::awt::ImagePosition; - sal_Int16 nImagePos = AwtImagePos::LeftCenter; + sal_Int16 nImagePos = ImagePosition::LeftCenter; switch( nPicPos ) { - case AX_PICPOS_LEFTTOP: nImagePos = AwtImagePos::LeftTop; break; - case AX_PICPOS_LEFTCENTER: nImagePos = AwtImagePos::LeftCenter; break; - case AX_PICPOS_LEFTBOTTOM: nImagePos = AwtImagePos::LeftBottom; break; - case AX_PICPOS_RIGHTTOP: nImagePos = AwtImagePos::RightTop; break; - case AX_PICPOS_RIGHTCENTER: nImagePos = AwtImagePos::RightCenter; break; - case AX_PICPOS_RIGHTBOTTOM: nImagePos = AwtImagePos::RightBottom; break; - case AX_PICPOS_ABOVELEFT: nImagePos = AwtImagePos::AboveLeft; break; - case AX_PICPOS_ABOVECENTER: nImagePos = AwtImagePos::AboveCenter; break; - case AX_PICPOS_ABOVERIGHT: nImagePos = AwtImagePos::AboveRight; break; - case AX_PICPOS_BELOWLEFT: nImagePos = AwtImagePos::BelowLeft; break; - case AX_PICPOS_BELOWCENTER: nImagePos = AwtImagePos::BelowCenter; break; - case AX_PICPOS_BELOWRIGHT: nImagePos = AwtImagePos::BelowRight; break; - case AX_PICPOS_CENTER: nImagePos = AwtImagePos::Centered; break; + case AX_PICPOS_LEFTTOP: nImagePos = ImagePosition::LeftTop; break; + case AX_PICPOS_LEFTCENTER: nImagePos = ImagePosition::LeftCenter; break; + case AX_PICPOS_LEFTBOTTOM: nImagePos = ImagePosition::LeftBottom; break; + case AX_PICPOS_RIGHTTOP: nImagePos = ImagePosition::RightTop; break; + case AX_PICPOS_RIGHTCENTER: nImagePos = ImagePosition::RightCenter; break; + case AX_PICPOS_RIGHTBOTTOM: nImagePos = ImagePosition::RightBottom; break; + case AX_PICPOS_ABOVELEFT: nImagePos = ImagePosition::AboveLeft; break; + case AX_PICPOS_ABOVECENTER: nImagePos = ImagePosition::AboveCenter; break; + case AX_PICPOS_ABOVERIGHT: nImagePos = ImagePosition::AboveRight; break; + case AX_PICPOS_BELOWLEFT: nImagePos = ImagePosition::BelowLeft; break; + case AX_PICPOS_BELOWCENTER: nImagePos = ImagePosition::BelowCenter; break; + case AX_PICPOS_BELOWRIGHT: nImagePos = ImagePosition::BelowRight; break; + case AX_PICPOS_CENTER: nImagePos = ImagePosition::Centered; break; default: OSL_ENSURE( false, "ControlConverter::convertAxPicture - unknown picture position" ); } rPropMap.setProperty( PROP_ImagePosition, nImagePos ); @@ -491,13 +459,12 @@ void ControlConverter::convertAxPicture( PropertyMap& rPropMap, const StreamData convertPicture( rPropMap, rPicData ); // picture scale mode - namespace AwtScaleMode = ::com::sun::star::awt::ImageScaleMode; - sal_Int16 nScaleMode = AwtScaleMode::None; + sal_Int16 nScaleMode = ImageScaleMode::None; switch( nPicSizeMode ) { - case AX_PICSIZE_CLIP: nScaleMode = AwtScaleMode::None; break; - case AX_PICSIZE_STRETCH: nScaleMode = AwtScaleMode::Anisotropic; break; - case AX_PICSIZE_ZOOM: nScaleMode = AwtScaleMode::Isotropic; break; + case AX_PICSIZE_CLIP: nScaleMode = ImageScaleMode::None; break; + case AX_PICSIZE_STRETCH: nScaleMode = ImageScaleMode::Anisotropic; break; + case AX_PICSIZE_ZOOM: nScaleMode = ImageScaleMode::Isotropic; break; default: OSL_ENSURE( false, "ControlConverter::convertAxPicture - unknown picture size mode" ); } rPropMap.setProperty( PROP_ScaleMode, nScaleMode ); @@ -565,6 +532,7 @@ OUString ControlModelBase::getServiceName() const case API_CONTROL_CHECKBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlCheckBoxModel" ); case API_CONTROL_RADIOBUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlRadioButtonModel" ); case API_CONTROL_EDIT: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlEditModel" ); + case API_CONTROL_NUMERIC: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlNumericFieldModel" ); case API_CONTROL_LISTBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlListBoxModel" ); case API_CONTROL_COMBOBOX: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlComboBoxModel" ); case API_CONTROL_SPINBUTTON: return CREATE_OUSTRING( "com.sun.star.awt.UnoControlSpinButtonModel" ); @@ -582,6 +550,7 @@ OUString ControlModelBase::getServiceName() const case API_CONTROL_CHECKBOX: return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" ); case API_CONTROL_RADIOBUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" ); case API_CONTROL_EDIT: return CREATE_OUSTRING( "com.sun.star.form.component.TextField" ); + case API_CONTROL_NUMERIC: return CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ); case API_CONTROL_LISTBOX: return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" ); case API_CONTROL_COMBOBOX: return CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ); case API_CONTROL_SPINBUTTON: return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" ); @@ -662,8 +631,8 @@ sal_uInt32 ComCtlModelBase::getDataPartId() const { switch( mnVersion ) { - case 5: return mnDataPartId5; - case 6: return mnDataPartId6; + case COMCTL_VERSION_50: return mnDataPartId5; + case COMCTL_VERSION_60: return mnDataPartId6; } OSL_ENSURE( false, "ComCtlObjectBase::getDataPartId - unxpected version" ); return SAL_MAX_UINT32; @@ -784,7 +753,7 @@ void ComCtlProgressBarModel::convertProperties( PropertyMap& rPropMap, const Con void ComCtlProgressBarModel::importControlData( BinaryInputStream& rInStrm ) { rInStrm >> mfMin >> mfMax; - if( mnVersion == 6 ) + if( mnVersion == COMCTL_VERSION_60 ) rInStrm >> mnVertical >> mnSmooth; } @@ -840,17 +809,15 @@ bool AxFontDataModel::importBinaryModel( BinaryInputStream& rInStrm ) void AxFontDataModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const { - namespace cssa = ::com::sun::star::awt; - // font name if( maFontData.maFontName.getLength() > 0 ) rPropMap.setProperty( PROP_FontName, maFontData.maFontName ); // font effects - rPropMap.setProperty( PROP_FontWeight, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_BOLD, cssa::FontWeight::BOLD, cssa::FontWeight::NORMAL ) ); - rPropMap.setProperty( PROP_FontSlant, getFlagValue< sal_Int16 >( maFontData.mnFontEffects, AX_FONTDATA_ITALIC, cssa::FontSlant_ITALIC, cssa::FontSlant_NONE ) ); - rPropMap.setProperty( PROP_FontUnderline, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_UNDERLINE, cssa::FontUnderline::SINGLE, cssa::FontUnderline::NONE ) ); - rPropMap.setProperty( PROP_FontStrikeout, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_STRIKEOUT, cssa::FontStrikeout::SINGLE, cssa::FontStrikeout::NONE ) ); + rPropMap.setProperty( PROP_FontWeight, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_BOLD, FontWeight::BOLD, FontWeight::NORMAL ) ); + rPropMap.setProperty( PROP_FontSlant, getFlagValue< sal_Int16 >( maFontData.mnFontEffects, AX_FONTDATA_ITALIC, FontSlant_ITALIC, FontSlant_NONE ) ); + rPropMap.setProperty( PROP_FontUnderline, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_UNDERLINE, maFontData.mbDblUnderline ? FontUnderline::DOUBLE : FontUnderline::SINGLE, FontUnderline::NONE ) ); + rPropMap.setProperty( PROP_FontStrikeout, getFlagValue( maFontData.mnFontEffects, AX_FONTDATA_STRIKEOUT, FontStrikeout::SINGLE, FontStrikeout::NONE ) ); rPropMap.setProperty( PROP_FontHeight, maFontData.getHeightPoints() ); // font character set @@ -863,12 +830,12 @@ void AxFontDataModel::convertProperties( PropertyMap& rPropMap, const ControlCon // text alignment if( mbSupportsAlign ) { - sal_Int32 nAlign = cssa::TextAlign::LEFT; + sal_Int32 nAlign = TextAlign::LEFT; switch( maFontData.mnHorAlign ) { - case AX_FONTDATA_LEFT: nAlign = cssa::TextAlign::LEFT; break; - case AX_FONTDATA_RIGHT: nAlign = cssa::TextAlign::RIGHT; break; - case AX_FONTDATA_CENTER: nAlign = cssa::TextAlign::CENTER; break; + case AX_FONTDATA_LEFT: nAlign = TextAlign::LEFT; break; + case AX_FONTDATA_RIGHT: nAlign = TextAlign::RIGHT; break; + case AX_FONTDATA_CENTER: nAlign = TextAlign::CENTER; break; default: OSL_ENSURE( false, "AxFontDataModel::convertProperties - unknown text alignment" ); } // form controls expect short value @@ -886,6 +853,7 @@ AxCommandButtonModel::AxCommandButtonModel() : mnBackColor( AX_SYSCOLOR_BUTTONFACE ), mnFlags( AX_CMDBUTTON_DEFFLAGS ), mnPicturePos( AX_PICPOS_ABOVECENTER ), + mnVerticalAlign( XML_Center ), mbFocusOnClick( true ) { } @@ -941,8 +909,8 @@ void AxCommandButtonModel::convertProperties( PropertyMap& rPropMap, const Contr rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) ); rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) ); rPropMap.setProperty( PROP_FocusOnClick, mbFocusOnClick ); - rPropMap.setProperty( PROP_VerticalAlign, ::com::sun::star::style::VerticalAlignment_MIDDLE ); rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor ); + rConv.convertVerticalAlign( rPropMap, mnVerticalAlign ); rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED ); rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos ); AxFontDataModel::convertProperties( rPropMap, rConv ); @@ -956,7 +924,8 @@ AxLabelModel::AxLabelModel() : mnFlags( AX_LABEL_DEFFLAGS ), mnBorderColor( AX_SYSCOLOR_WINDOWFRAME ), mnBorderStyle( AX_BORDERSTYLE_NONE ), - mnSpecialEffect( AX_SPECIALEFFECT_FLAT ) + mnSpecialEffect( AX_SPECIALEFFECT_FLAT ), + mnVerticalAlign( XML_Top ) { } @@ -1004,8 +973,8 @@ void AxLabelModel::convertProperties( PropertyMap& rPropMap, const ControlConver rPropMap.setProperty( PROP_Label, maCaption ); rPropMap.setProperty( PROP_Enabled, getFlag( mnFlags, AX_FLAGS_ENABLED ) ); rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) ); - rPropMap.setProperty( PROP_VerticalAlign, ::com::sun::star::style::VerticalAlignment_TOP ); rConv.convertColor( rPropMap, PROP_TextColor, mnTextColor ); + rConv.convertVerticalAlign( rPropMap, mnVerticalAlign ); rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID ); rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect ); AxFontDataModel::convertProperties( rPropMap, rConv ); @@ -1102,7 +1071,8 @@ AxMorphDataModelBase::AxMorphDataModelBase() : mnShowDropButton( AX_SHOWDROPBUTTON_NEVER ), mnMaxLength( 0 ), mnPasswordChar( 0 ), - mnListRows( 8 ) + mnListRows( 8 ), + mnVerticalAlign( XML_Center ) { } @@ -1191,6 +1161,7 @@ void AxMorphDataModelBase::convertProperties( PropertyMap& rPropMap, const Contr AxToggleButtonModel::AxToggleButtonModel() { + mnDisplayStyle = AX_DISPLAYSTYLE_TOGGLE; } ApiControlType AxToggleButtonModel::getControlType() const @@ -1203,8 +1174,8 @@ void AxToggleButtonModel::convertProperties( PropertyMap& rPropMap, const Contro { rPropMap.setProperty( PROP_Label, maCaption ); rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) ); - rPropMap.setProperty( PROP_VerticalAlign, ::com::sun::star::style::VerticalAlignment_MIDDLE ); rPropMap.setProperty( PROP_Toggle, true ); + rConv.convertVerticalAlign( rPropMap, mnVerticalAlign ); rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_NOTSUPPORTED ); rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos ); rConv.convertAxState( rPropMap, maValue, mnMultiSelect, API_DEFAULTSTATE_BOOLEAN, mbAwtModel ); @@ -1215,6 +1186,7 @@ void AxToggleButtonModel::convertProperties( PropertyMap& rPropMap, const Contro AxCheckBoxModel::AxCheckBoxModel() { + mnDisplayStyle = AX_DISPLAYSTYLE_CHECKBOX; } ApiControlType AxCheckBoxModel::getControlType() const @@ -1227,7 +1199,7 @@ void AxCheckBoxModel::convertProperties( PropertyMap& rPropMap, const ControlCon { rPropMap.setProperty( PROP_Label, maCaption ); rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) ); - rPropMap.setProperty( PROP_VerticalAlign, ::com::sun::star::style::VerticalAlignment_MIDDLE ); + rConv.convertVerticalAlign( rPropMap, mnVerticalAlign ); rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID ); rConv.convertAxVisualEffect( rPropMap, mnSpecialEffect ); rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos ); @@ -1239,6 +1211,7 @@ void AxCheckBoxModel::convertProperties( PropertyMap& rPropMap, const ControlCon AxOptionButtonModel::AxOptionButtonModel() { + mnDisplayStyle = AX_DISPLAYSTYLE_OPTBUTTON; } ApiControlType AxOptionButtonModel::getControlType() const @@ -1251,7 +1224,7 @@ void AxOptionButtonModel::convertProperties( PropertyMap& rPropMap, const Contro { rPropMap.setProperty( PROP_Label, maCaption ); rPropMap.setProperty( PROP_MultiLine, getFlag( mnFlags, AX_FLAGS_WORDWRAP ) ); - rPropMap.setProperty( PROP_VerticalAlign, ::com::sun::star::style::VerticalAlignment_MIDDLE ); + rConv.convertVerticalAlign( rPropMap, mnVerticalAlign ); rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID ); rConv.convertAxVisualEffect( rPropMap, mnSpecialEffect ); rConv.convertAxPicture( rPropMap, maPictureData, mnPicturePos ); @@ -1263,6 +1236,7 @@ void AxOptionButtonModel::convertProperties( PropertyMap& rPropMap, const Contro AxTextBoxModel::AxTextBoxModel() { + mnDisplayStyle = AX_DISPLAYSTYLE_TEXT; } ApiControlType AxTextBoxModel::getControlType() const @@ -1288,8 +1262,34 @@ void AxTextBoxModel::convertProperties( PropertyMap& rPropMap, const ControlConv // ============================================================================ +AxNumericFieldModel::AxNumericFieldModel() +{ + mnDisplayStyle = AX_DISPLAYSTYLE_TEXT; +} + +ApiControlType AxNumericFieldModel::getControlType() const +{ + OSL_ENSURE( mnDisplayStyle == AX_DISPLAYSTYLE_TEXT, "AxNumericFieldModel::getControlType - invalid control type" ); + return API_CONTROL_NUMERIC; +} + +void AxNumericFieldModel::convertProperties( PropertyMap& rPropMap, const ControlConverter& rConv ) const +{ + rPropMap.setProperty( PROP_HideInactiveSelection, getFlag( mnFlags, AX_FLAGS_HIDESELECTION ) ); + // TODO: OUString::toDouble() does not handle local decimal separator + rPropMap.setProperty( mbAwtModel ? PROP_Value : PROP_DefaultValue, maValue.toDouble() ); + rPropMap.setProperty( PROP_Spin, getFlag( mnScrollBars, AX_SCROLLBAR_VERTICAL ) ); + rPropMap.setProperty( PROP_Repeat, true ); + rConv.convertAxBackground( rPropMap, mnBackColor, mnFlags, API_TRANSPARENCY_VOID ); + rConv.convertAxBorder( rPropMap, mnBorderColor, mnBorderStyle, mnSpecialEffect ); + AxMorphDataModelBase::convertProperties( rPropMap, rConv ); +} + +// ============================================================================ + AxListBoxModel::AxListBoxModel() { + mnDisplayStyle = AX_DISPLAYSTYLE_LISTBOX; } ApiControlType AxListBoxModel::getControlType() const @@ -1312,6 +1312,7 @@ void AxListBoxModel::convertProperties( PropertyMap& rPropMap, const ControlConv AxComboBoxModel::AxComboBoxModel() { + mnDisplayStyle = AX_DISPLAYSTYLE_COMBOBOX; } ApiControlType AxComboBoxModel::getControlType() const @@ -1500,7 +1501,7 @@ void AxScrollBarModel::convertProperties( PropertyMap& rPropMap, const ControlCo // ============================================================================ AxTabStripModel::AxTabStripModel() : - AxFontDataModel( false ), // no support for Align property + AxFontDataModel( false ), // no support for alignment properties mnBackColor( AX_SYSCOLOR_BUTTONFACE ), mnTextColor( AX_SYSCOLOR_BUTTONTEXT ), mnFlags( AX_TABSTRIP_DEFFLAGS ), @@ -1562,7 +1563,7 @@ OUString AxTabStripModel::getCaption( sal_Int32 nIndex ) const // ============================================================================ AxContainerModelBase::AxContainerModelBase( bool bFontSupport ) : - AxFontDataModel( false ), // no support for Align property + AxFontDataModel( false ), // no support for alignment properties maLogicalSize( AX_CONTAINER_DEFWIDTH, AX_CONTAINER_DEFHEIGHT ), maScrollPos( 0, 0 ), mnBackColor( AX_SYSCOLOR_BUTTONFACE ), @@ -1755,43 +1756,26 @@ EmbeddedControl::~EmbeddedControl() { } -ControlModelRef EmbeddedControl::createModel( const OUString& rClassId ) +ControlModelBase* EmbeddedControl::createModelFromGuid( const OUString& rClassId ) { OUString aClassId = rClassId.toAsciiUpperCase(); - if( aClassId.equalsAscii( AX_GUID_COMMANDBUTTON ) ) - mxModel.reset( new AxCommandButtonModel ); - else if( aClassId.equalsAscii( AX_GUID_LABEL ) ) - mxModel.reset( new AxLabelModel ); - else if( aClassId.equalsAscii( AX_GUID_IMAGE ) ) - mxModel.reset( new AxImageModel ); - else if( aClassId.equalsAscii( AX_GUID_TOGGLEBUTTON ) ) - mxModel.reset( new AxToggleButtonModel ); - else if( aClassId.equalsAscii( AX_GUID_CHECKBOX ) ) - mxModel.reset( new AxCheckBoxModel ); - else if( aClassId.equalsAscii( AX_GUID_OPTIONBUTTON ) ) - mxModel.reset( new AxOptionButtonModel ); - else if( aClassId.equalsAscii( AX_GUID_TEXTBOX ) ) - mxModel.reset( new AxTextBoxModel ); - else if( aClassId.equalsAscii( AX_GUID_LISTBOX ) ) - mxModel.reset( new AxListBoxModel ); - else if( aClassId.equalsAscii( AX_GUID_COMBOBOX ) ) - mxModel.reset( new AxComboBoxModel ); - else if( aClassId.equalsAscii( AX_GUID_SPINBUTTON ) ) - mxModel.reset( new AxSpinButtonModel ); - else if( aClassId.equalsAscii( AX_GUID_SCROLLBAR ) ) - mxModel.reset( new AxScrollBarModel ); - else if( aClassId.equalsAscii( AX_GUID_FRAME ) ) - mxModel.reset( new AxFrameModel ); - else if( aClassId.equalsAscii( COMCTL_GUID_SCROLLBAR_60 ) ) - mxModel.reset( new ComCtlScrollBarModel( 6 ) ); - else - mxModel.reset(); - // embedded controls are form component instances - if( mxModel.get() ) - mxModel->setFormComponentMode(); + if( aClassId.equalsAscii( AX_GUID_COMMANDBUTTON ) ) return &createModel< AxCommandButtonModel >(); + if( aClassId.equalsAscii( AX_GUID_LABEL ) ) return &createModel< AxLabelModel >(); + if( aClassId.equalsAscii( AX_GUID_IMAGE ) ) return &createModel< AxImageModel >(); + if( aClassId.equalsAscii( AX_GUID_TOGGLEBUTTON ) ) return &createModel< AxToggleButtonModel >(); + if( aClassId.equalsAscii( AX_GUID_CHECKBOX ) ) return &createModel< AxCheckBoxModel >(); + if( aClassId.equalsAscii( AX_GUID_OPTIONBUTTON ) ) return &createModel< AxOptionButtonModel >(); + if( aClassId.equalsAscii( AX_GUID_TEXTBOX ) ) return &createModel< AxTextBoxModel >(); + if( aClassId.equalsAscii( AX_GUID_LISTBOX ) ) return &createModel< AxListBoxModel >(); + if( aClassId.equalsAscii( AX_GUID_COMBOBOX ) ) return &createModel< AxComboBoxModel >(); + if( aClassId.equalsAscii( AX_GUID_SPINBUTTON ) ) return &createModel< AxSpinButtonModel >(); + if( aClassId.equalsAscii( AX_GUID_SCROLLBAR ) ) return &createModel< AxScrollBarModel >(); + if( aClassId.equalsAscii( AX_GUID_FRAME ) ) return &createModel< AxFrameModel >(); + if( aClassId.equalsAscii( COMCTL_GUID_SCROLLBAR_60 ) ) return &createModel< ComCtlScrollBarModel >( COMCTL_VERSION_60 ); - return mxModel; + mxModel.reset(); + return 0; } OUString EmbeddedControl::getServiceName() const @@ -1817,14 +1801,14 @@ bool EmbeddedControl::convertProperties( const Reference< XControlModel >& rxCtr EmbeddedForm::EmbeddedForm( const Reference< XModel >& rxDocModel, const Reference< XDrawPage >& rxDrawPage, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr ) : - ControlConverter( rxDocModel, rGraphicHelper, bDefaultColorBgr ), + maControlConv( rxDocModel, rGraphicHelper, bDefaultColorBgr ), mxModelFactory( rxDocModel, UNO_QUERY ), mxFormsSupp( rxDrawPage, UNO_QUERY ) { OSL_ENSURE( mxModelFactory.is(), "EmbeddedForm::EmbeddedForm - missing service factory" ); } -Reference< XControlModel > EmbeddedForm::convertAndInsert( const EmbeddedControl& rControl ) +Reference< XControlModel > EmbeddedForm::convertAndInsert( const EmbeddedControl& rControl, sal_Int32& rnCtrlIndex ) { if( mxModelFactory.is() && rControl.hasModel() ) try { @@ -1834,12 +1818,12 @@ Reference< XControlModel > EmbeddedForm::convertAndInsert( const EmbeddedControl Reference< XControlModel > xCtrlModel( xFormComp, UNO_QUERY_THROW ); // insert the control into the form - Reference< XIndexContainer > xFormIC( createForm(), UNO_SET_THROW ); - sal_Int32 nNewIndex = xFormIC->getCount(); - xFormIC->insertByIndex( nNewIndex, Any( xFormComp ) ); + Reference< XIndexContainer > xFormIC( createXForm(), UNO_SET_THROW ); + rnCtrlIndex = xFormIC->getCount(); + xFormIC->insertByIndex( rnCtrlIndex, Any( xFormComp ) ); // convert the control properties - if( rControl.convertProperties( xCtrlModel, *this ) ) + if( rControl.convertProperties( xCtrlModel, maControlConv ) ) return xCtrlModel; } catch( Exception& ) @@ -1848,7 +1832,7 @@ Reference< XControlModel > EmbeddedForm::convertAndInsert( const EmbeddedControl return Reference< XControlModel >(); } -Reference< XIndexContainer > EmbeddedForm::createForm() +Reference< XIndexContainer > EmbeddedForm::createXForm() { if( mxFormsSupp.is() ) { diff --git a/oox/source/ole/axcontrolfragment.cxx b/oox/source/ole/axcontrolfragment.cxx index ecd782da2cb0..b57807a41df6 100644 --- a/oox/source/ole/axcontrolfragment.cxx +++ b/oox/source/ole/axcontrolfragment.cxx @@ -105,7 +105,7 @@ ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const switch( rAttribs.getToken( AX_TOKEN( persistence ), XML_TOKEN_INVALID ) ) { case XML_persistPropertyBag: - if( ControlModelBase* pModel = mrControl.createModel( aClassId ).get() ) + if( ControlModelBase* pModel = mrControl.createModelFromGuid( aClassId ) ) return new AxControlPropertyContext( *this, *pModel ); break; @@ -121,7 +121,7 @@ ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const OUString aStrmClassId = OleHelper::importGuid( aInStrm ); OSL_ENSURE( aClassId.equalsIgnoreAsciiCase( aStrmClassId ), "AxControlFragment::importBinaryControl - form control class ID mismatch" ); - if( ControlModelBase* pModel = mrControl.createModel( aStrmClassId ).get() ) + if( ControlModelBase* pModel = mrControl.createModelFromGuid( aStrmClassId ) ) pModel->importBinaryModel( aInStrm ); } } @@ -139,7 +139,7 @@ ContextHandlerRef AxControlFragment::onCreateContext( sal_Int32 nElement, const OleStorage aStorage( getFilter().getGlobalFactory(), xStrgStrm, false ); BinaryXInputStream aInStrm( aStorage.openInputStream( CREATE_OUSTRING( "f" ) ), true ); if( !aInStrm.isEof() ) - if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModel( aClassId ).get() ) ) + if( AxContainerModelBase* pModel = dynamic_cast< AxContainerModelBase* >( mrControl.createModelFromGuid( aClassId ) ) ) pModel->importBinaryModel( aInStrm ); } } diff --git a/oox/source/ole/olehelper.cxx b/oox/source/ole/olehelper.cxx index 0a0796e15a7e..8952350c8589 100644 --- a/oox/source/ole/olehelper.cxx +++ b/oox/source/ole/olehelper.cxx @@ -51,10 +51,16 @@ const sal_uInt32 OLE_PALETTECOLOR_MASK = 0x0000FFFF; const sal_uInt32 OLE_BGRCOLOR_MASK = 0x00FFFFFF; const sal_uInt32 OLE_SYSTEMCOLOR_MASK = 0x0000FFFF; +/** Swaps the red and blue component of the passed color. */ +inline sal_uInt32 lclSwapRedBlue( sal_uInt32 nColor ) +{ + return static_cast< sal_uInt32 >( (nColor & 0xFF00FF00) | ((nColor & 0x0000FF) << 16) | ((nColor & 0xFF0000) >> 16) ); +} + /** Returns the UNO RGB color from the passed encoded OLE BGR color. */ inline sal_Int32 lclDecodeBgrColor( sal_uInt32 nOleColor ) { - return static_cast< sal_Int32 >( ((nOleColor & 0x0000FF) << 16) | (nOleColor & 0x00FF00) | ((nOleColor & 0xFF0000) >> 16) ); + return static_cast< sal_Int32 >( lclSwapRedBlue( nOleColor ) & 0xFFFFFF ); } // ---------------------------------------------------------------------------- @@ -161,6 +167,11 @@ StdFontInfo::StdFontInfo( const ::rtl::OUString& rName, sal_uInt32 nHeight, return API_RGB_BLACK; } +/*static*/ sal_uInt32 OleHelper::encodeOleColor( sal_Int32 nRgbColor ) +{ + return OLE_COLORTYPE_BGR | lclSwapRedBlue( static_cast< sal_uInt32 >( nRgbColor & 0xFFFFFF ) ); +} + /*static*/ OUString OleHelper::importGuid( BinaryInputStream& rInStrm ) { OUStringBuffer aBuffer; diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx index fbc5306763a6..39306040fd66 100755 --- a/oox/source/ole/vbaproject.cxx +++ b/oox/source/ole/vbaproject.cxx @@ -31,10 +31,12 @@ #include <com/sun/star/document/XStorageBasedDocument.hpp> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/embed/XTransactedObject.hpp> +#include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/script/ModuleType.hpp> #include <com/sun/star/script/XLibraryContainer.hpp> #include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/script/vba/XVBAMacroResolver.hpp> #include <comphelper/configurationhelper.hxx> #include <comphelper/string.hxx> #include <rtl/tencinfo.h> @@ -63,6 +65,7 @@ using namespace ::com::sun::star::frame; using namespace ::com::sun::star::io; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::script; +using namespace ::com::sun::star::script::vba; using namespace ::com::sun::star::uno; using ::comphelper::ConfigurationHelper; @@ -127,12 +130,35 @@ bool VbaFilterConfig::isExportVba() const // ============================================================================ +VbaMacroAttacherBase::VbaMacroAttacherBase( const OUString& rMacroName ) : + maMacroName( rMacroName ) +{ + OSL_ENSURE( maMacroName.getLength() > 0, "VbaMacroAttacherBase::VbaMacroAttacherBase - empty macro name" ); +} + +VbaMacroAttacherBase::~VbaMacroAttacherBase() +{ +} + +void VbaMacroAttacherBase::resolveAndAttachMacro( const Reference< XVBAMacroResolver >& rxResolver ) +{ + try + { + attachMacro( rxResolver->resolveVBAMacroToScriptURL( maMacroName ) ); + } + catch( Exception& ) + { + } +} + +// ============================================================================ + VbaProject::VbaProject( const Reference< XMultiServiceFactory >& rxGlobalFactory, const Reference< XModel >& rxDocModel, const OUString& rConfigCompName ) : VbaFilterConfig( rxGlobalFactory, rConfigCompName ), mxGlobalFactory( rxGlobalFactory ), mxDocModel( rxDocModel ), - maLibName( CREATE_OUSTRING( "Standard" ) ) + maPrjName( CREATE_OUSTRING( "Standard" ) ) { OSL_ENSURE( mxDocModel.is(), "VbaProject::VbaProject - missing document model" ); mxBasicLib = openLibrary( PROP_BasicLibraries, false ); @@ -156,6 +182,12 @@ void VbaProject::importVbaProject( StorageBase& rVbaPrjStrg, const GraphicHelper } } +void VbaProject::registerMacroAttacher( const VbaMacroAttacherRef& rxAttacher ) +{ + OSL_ENSURE( rxAttacher.get(), "VbaProject::registerMacroAttacher - unexpected empty reference" ); + maMacroAttachers.push_back( rxAttacher ); +} + bool VbaProject::hasModules() const { return mxBasicLib.is() && mxBasicLib->hasElements(); @@ -200,7 +232,7 @@ bool VbaProject::attachMacroToEvent( const Reference< XEventsSupplier >& rxEvent // check that the specified macro exists in the module VbaHelper::hasMacro( mxBasicLib, rModuleName, rMacroName ) && // attach the macro to the events supplier - VbaHelper::attachMacroToEvent( rxEventsSupp, rEventName, maLibName, rModuleName, rMacroName ); + VbaHelper::attachMacroToEvent( rxEventsSupp, rEventName, CREATE_OUSTRING( "Standard" ) /*maPrjName*/, rModuleName, rMacroName ); } bool VbaProject::attachMacroToDocumentEvent( const OUString& rEventName, @@ -227,7 +259,7 @@ bool VbaProject::attachMacroToEvent( const Reference< XEventsSupplier >& rxEvent // insert the new macro into the code module and attach it to the event return VbaHelper::insertMacro( mxBasicLib, rModuleName, aProxyName, rProxyArgs, rProxyType, aProxyCode ) && - VbaHelper::attachMacroToEvent( rxEventsSupp, rEventName, maLibName, rModuleName, aProxyName ); + VbaHelper::attachMacroToEvent( rxEventsSupp, rEventName, CREATE_OUSTRING( "Standard" ) /*maPrjName*/, rModuleName, aProxyName ); } return false; } @@ -248,7 +280,11 @@ void VbaProject::addDummyModule( const OUString& rName, sal_Int32 nType ) maDummyModules[ rName ] = nType; } -void VbaProject::prepareModuleImport() +void VbaProject::prepareImport() +{ +} + +void VbaProject::finalizeImport() { } @@ -267,9 +303,9 @@ Reference< XNameContainer > VbaProject::openLibrary( sal_Int32 nPropId, bool bCr try { Reference< XLibraryContainer > xLibContainer( getLibraryContainer( nPropId ), UNO_SET_THROW ); - if( bCreateMissing && !xLibContainer->hasByName( maLibName ) ) - xLibContainer->createLibrary( maLibName ); - xLibrary.set( xLibContainer->getByName( maLibName ), UNO_QUERY_THROW ); + if( bCreateMissing && !xLibContainer->hasByName( CREATE_OUSTRING( "Standard" ) /*maPrjName*/ ) ) + xLibContainer->createLibrary( CREATE_OUSTRING( "Standard" ) /*maPrjName*/ ); + xLibrary.set( xLibContainer->getByName( CREATE_OUSTRING( "Standard" ) /*maPrjName*/ ), UNO_QUERY_THROW ); } catch( Exception& ) { @@ -311,7 +347,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap return; // virtual call, derived classes may do some preparations - prepareModuleImport(); + prepareImport(); // read all records of the directory rtl_TextEncoding eTextEnc = RTL_TEXTENCODING_MS_1252; @@ -341,6 +377,14 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap eTextEnc = eNewTextEnc; } break; + case VBA_ID_PROJECTNAME: + { + OUString aPrjName = aRecStrm.readCharArrayUC( nRecSize, eTextEnc ); + OSL_ENSURE( aPrjName.getLength() > 0, "VbaProject::importVba - invalid project name" ); + if( aPrjName.getLength() > 0 ) + maPrjName = aPrjName; + } + break; case VBA_ID_PROJECTMODULES: OOX_ENSURE_RECORDSIZE( nRecSize == 2 ); OSL_ENSURE( aModules.empty(), "VbaProject::importVba - unexpected PROJECTMODULES record" ); @@ -438,10 +482,10 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap } /* Now it is time to load the source code. All modules will be inserted - into the Basic library of the document specified by the 'maLibName' + into the Basic library of the document specified by the 'maPrjName' member. Do not create the Basic library, if there are no modules specified. */ - if( !aModules.empty() && !aDummyModules.empty() ) try + if( !aModules.empty() || !aDummyModules.empty() ) try { // get the basic library Reference< XNameContainer > xBasicLib( createBasicLibrary(), UNO_SET_THROW ); @@ -516,6 +560,27 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap } } } + + // attach macros to registered objects + attachMacros(); + // virtual call, derived classes may do some more processing + finalizeImport(); +} + +void VbaProject::attachMacros() +{ + if( !maMacroAttachers.empty() ) try + { + Sequence< Any > aArgs( 2 ); + aArgs[ 0 ] <<= mxDocModel; + aArgs[ 1 ] <<= maPrjName; + Reference< XVBAMacroResolver > xResolver( mxGlobalFactory->createInstanceWithArguments( + CREATE_OUSTRING( "com.sun.star.script.vba.VBAMacroResolver" ), aArgs ), UNO_QUERY_THROW ); + maMacroAttachers.forEachMem( &VbaMacroAttacherBase::resolveAndAttachMacro, ::boost::cref( xResolver ) ); + } + catch( Exception& ) + { + } } void VbaProject::copyStorage( StorageBase& rVbaPrjStrg ) diff --git a/oox/source/ppt/pptimport.cxx b/oox/source/ppt/pptimport.cxx index d60629b4481b..b3cd99ad6166 100644 --- a/oox/source/ppt/pptimport.cxx +++ b/oox/source/ppt/pptimport.cxx @@ -30,6 +30,7 @@ #include "oox/dump/pptxdumper.hxx" #include "oox/drawingml/table/tablestylelistfragmenthandler.hxx" #include "oox/helper/graphichelper.hxx" +#include "oox/ole/vbaproject.hxx" using ::rtl::OUString; using namespace ::com::sun::star; @@ -180,6 +181,11 @@ GraphicHelper* PowerPointImport::implCreateGraphicHelper() const return new PptGraphicHelper( *this ); } +::oox::ole::VbaProject* PowerPointImport::implCreateVbaProject() const +{ + return new ::oox::ole::VbaProject( getGlobalFactory(), getModel(), CREATE_OUSTRING( "Impress" ) ); +} + OUString PowerPointImport::implGetImplementationName() const { return PowerPointImport_getImplementationName(); diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx index bfe3ead6ca04..60144bbbe79d 100644 --- a/oox/source/ppt/pptshape.cxx +++ b/oox/source/ppt/pptshape.cxx @@ -64,7 +64,7 @@ PPTShape::~PPTShape() } void PPTShape::addShape( - const oox::core::XmlFilterBase& rFilterBase, + oox::core::XmlFilterBase& rFilterBase, const SlidePersist& rSlidePersist, const oox::drawingml::Theme* pTheme, const Reference< XShapes >& rxShapes, diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx index ce99ffc49f19..f4dee1216937 100644 --- a/oox/source/ppt/slidepersist.cxx +++ b/oox/source/ppt/slidepersist.cxx @@ -129,7 +129,7 @@ sal_Int16 SlidePersist::getLayoutFromValueToken() return nLayout; } -void SlidePersist::createXShapes( const XmlFilterBase& rFilterBase ) +void SlidePersist::createXShapes( XmlFilterBase& rFilterBase ) { applyTextStyles( rFilterBase ); diff --git a/oox/source/shape/ShapeContextHandler.cxx b/oox/source/shape/ShapeContextHandler.cxx index e253d43e56e7..9313184d6865 100644 --- a/oox/source/shape/ShapeContextHandler.cxx +++ b/oox/source/shape/ShapeContextHandler.cxx @@ -68,7 +68,7 @@ ShapeContextHandler::getGraphicShapeContext(::sal_Int32 Element ) switch (Element & 0xffff) { case XML_graphic: - mpShape.reset(new Shape("com.sun.star.drawing.OLE2Shape" )); + mpShape.reset(new Shape("com.sun.star.drawing.GraphicObjectShape" )); mxGraphicShapeContext.set (new GraphicalObjectFrameContext(*rFragmentHandler, pMasterShape, mpShape, true)); break; diff --git a/oox/source/shape/ShapeFilterBase.cxx b/oox/source/shape/ShapeFilterBase.cxx index 7ed001ffc96c..c0a4857479a7 100644 --- a/oox/source/shape/ShapeFilterBase.cxx +++ b/oox/source/shape/ShapeFilterBase.cxx @@ -27,6 +27,7 @@ #include "ShapeFilterBase.hxx" #include "oox/drawingml/chart/chartconverter.hxx" +#include "oox/ole/vbaproject.hxx" namespace oox { namespace shape { @@ -65,6 +66,11 @@ const ::oox::drawingml::table::TableStyleListPtr ShapeFilterBase::getTableStyles return *mxChartConv; } +::oox::ole::VbaProject* ShapeFilterBase::implCreateVbaProject() const +{ + return new ::oox::ole::VbaProject( getGlobalFactory(), getModel(), CREATE_OUSTRING( "Writer" ) ); +} + ::rtl::OUString ShapeFilterBase::implGetImplementationName() const { return ::rtl::OUString(); diff --git a/oox/source/shape/ShapeFilterBase.hxx b/oox/source/shape/ShapeFilterBase.hxx index 09cbc75e01aa..748b92389b0c 100644 --- a/oox/source/shape/ShapeFilterBase.hxx +++ b/oox/source/shape/ShapeFilterBase.hxx @@ -60,12 +60,13 @@ public: virtual ::oox::drawingml::chart::ChartConverter& getChartConverter(); - virtual rtl::OUString implGetImplementationName() const; - virtual bool importDocument() { return true; } virtual bool exportDocument() { return true; } private: + virtual ::oox::ole::VbaProject* implCreateVbaProject() const; + virtual rtl::OUString implGetImplementationName() const; + ::boost::shared_ptr< ::oox::drawingml::chart::ChartConverter > mxChartConv; }; diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 243351cff050..8d02aa6e5256 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -9,6 +9,7 @@ AdjustLuminance AdjustmentValues Align AnchorPosition +ApplyFormDesignMode ArrangeOrder Aspect AttachedAxisIndex @@ -110,6 +111,7 @@ DefaultScrollValue DefaultSpinValue DefaultState DefaultText +DefaultValue DiagonalBLTR DiagonalTLBR DialogLibraries @@ -387,6 +389,7 @@ SortInfo Sound SoundOn Speed +Spin SpinIncrement SpinValue SpinValueMax @@ -445,6 +448,7 @@ UseRings UseSelectedPage VScroll Validation +Value VaryColorsByPoint VertJustify VerticalAlign diff --git a/oox/source/token/tokens.txt b/oox/source/token/tokens.txt index b05a21152722..13c1a10ff9b4 100644 --- a/oox/source/token/tokens.txt +++ b/oox/source/token/tokens.txt @@ -63,6 +63,7 @@ BookSection BookTitle BorderColor BorderStyle +Bottom BroadcastTitle Broadcaster Button @@ -72,6 +73,7 @@ Cancel Caption Case CaseNumber +Center ChapterNumber Characters CharactersWithSpaces @@ -82,6 +84,8 @@ ClientData ColHidden Colored Column +Combo +ComboEdit Comments Company Compiler @@ -116,6 +120,7 @@ Director Disabled Dismiss DisplayStyle +Distributed Distributor DocSecurity DocumentFromInternetSite @@ -134,6 +139,7 @@ Editor ElectronicSource Embed EnhancedMetaFile +Extend Extension External False @@ -190,11 +196,13 @@ Issue JournalArticle JournalName JustLastX +Justify LCID LCT Label LargeChange Last +Left LineA Lines Link @@ -239,6 +247,7 @@ MouseIcon MousePointer MoveWithCells Movie +Multi MultiLine MultiSel MultiSelect @@ -315,6 +324,7 @@ Relationships RelationshipsGroupReference Report Reporter +Right RootElement Row RowHidden @@ -340,6 +350,8 @@ ShortTitle ShowDropButtonWhen ShowImportExportValidationErrors SignatureTime +Simple +Single Size SizeMode SizeWithCells @@ -367,6 +379,7 @@ Theater ThesisType Title TitlesOfParts +Top TotalTime Translator True @@ -2087,6 +2100,7 @@ fNode fPr fPrintsWithSheet fPublished +face facet fact factor @@ -2249,6 +2263,7 @@ followColorScheme followSib followedHyperlink font +font4 fontAlgn fontColor fontId diff --git a/oox/source/vml/makefile.mk b/oox/source/vml/makefile.mk index 2b47a1c930db..094d37cd8c1c 100644 --- a/oox/source/vml/makefile.mk +++ b/oox/source/vml/makefile.mk @@ -41,13 +41,15 @@ ENABLE_EXCEPTIONS=TRUE # --- Files -------------------------------------------------------- SLOFILES = \ - $(SLO)$/vmldrawing.obj \ - $(SLO)$/vmldrawingfragment.obj \ - $(SLO)$/vmlformatting.obj \ - $(SLO)$/vmlinputstream.obj \ - $(SLO)$/vmlshape.obj \ - $(SLO)$/vmlshapecontainer.obj \ - $(SLO)$/vmlshapecontext.obj + $(SLO)$/vmldrawing.obj \ + $(SLO)$/vmldrawingfragment.obj \ + $(SLO)$/vmlformatting.obj \ + $(SLO)$/vmlinputstream.obj \ + $(SLO)$/vmlshape.obj \ + $(SLO)$/vmlshapecontainer.obj \ + $(SLO)$/vmlshapecontext.obj \ + $(SLO)$/vmltextbox.obj \ + $(SLO)$/vmltextboxcontext.obj # --- Targets ------------------------------------------------------- diff --git a/oox/source/vml/vmldrawing.cxx b/oox/source/vml/vmldrawing.cxx index 56afb8cf76e9..065558d68c9f 100644 --- a/oox/source/vml/vmldrawing.cxx +++ b/oox/source/vml/vmldrawing.cxx @@ -27,12 +27,15 @@ #include "oox/vml/vmldrawing.hxx" +#include <algorithm> +#include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/drawing/XShapes.hpp> -#include "tokens.hxx" +#include <com/sun/star/lang/XMultiServiceFactory.hpp> #include "oox/core/xmlfilterbase.hxx" #include "oox/ole/axcontrol.hxx" #include "oox/vml/vmlshape.hxx" #include "oox/vml/vmlshapecontainer.hxx" +#include "tokens.hxx" namespace oox { namespace vml { @@ -41,6 +44,7 @@ namespace vml { using namespace ::com::sun::star::awt; using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using ::oox::core::XmlFilterBase; @@ -57,6 +61,13 @@ OUString lclGetShapeId( sal_Int32 nShapeId ) return CREATE_OUSTRING( "\0s" ) + OUString::valueOf( nShapeId ); } +/** Returns the numeric VML shape identifier from its textual representation. */ +sal_Int32 lclGetShapeId( const OUString& rShapeId ) +{ + // identifier consists of a literal NUL character, a lowercase 's', and the id + return ((rShapeId.getLength() >= 3) && (rShapeId[ 0 ] == '\0') && (rShapeId[ 1 ] == 's')) ? rShapeId.copy( 2 ).toInt32() : -1; +} + } // namespace // ============================================================================ @@ -106,6 +117,18 @@ Drawing::~Drawing() return *mxCtrlForm; } +void Drawing::registerBlockId( sal_Int32 nBlockId ) +{ + OSL_ENSURE( nBlockId > 0, "Drawing::registerBlockId - invalid block index" ); + if( nBlockId > 0 ) + { + // lower_bound() returns iterator pointing to element equal to nBlockId, if existing + BlockIdVector::iterator aIt = ::std::lower_bound( maBlockIds.begin(), maBlockIds.end(), nBlockId ); + if( (aIt == maBlockIds.end()) || (nBlockId != *aIt) ) + maBlockIds.insert( aIt, nBlockId ); + } +} + void Drawing::registerOleObject( const OleObjectInfo& rOleObject ) { OSL_ENSURE( rOleObject.maShapeId.getLength() > 0, "Drawing::registerOleObject - missing OLE object shape id" ); @@ -132,6 +155,47 @@ void Drawing::convertAndInsert() const mxShapes->convertAndInsert( xShapes ); } +sal_Int32 Drawing::getLocalShapeIndex( const OUString& rShapeId ) const +{ + sal_Int32 nShapeId = lclGetShapeId( rShapeId ); + if( nShapeId <= 0 ) return -1; + + /* Shapes in a drawing are counted per registered shape identifier blocks + as stored in the o:idmap element. The contents of this element have + been stored in our member maBlockIds. Each block represents 1024 shape + identifiers, starting with identifier 1 for the block #0. This means, + block #0 represents the identifiers 1-1024, block #1 represents the + identifiers 1025-2048, and so on. The local shape index has to be + calculated according to all blocks registered for this drawing. + + Example: + Registered for this drawing are blocks #1 and #3 (shape identifiers + 1025-2048 and 3073-4096). + Shape identifier 1025 -> local shape index 1. + Shape identifier 1026 -> local shape index 2. + ... + Shape identifier 2048 -> local shape index 1024. + Shape identifier 3073 -> local shape index 1025. + ... + Shape identifier 4096 -> local shape index 2048. + */ + + // get block id from shape id and find its index in the list of used blocks + sal_Int32 nBlockId = (nShapeId - 1) / 1024; + BlockIdVector::iterator aIt = ::std::lower_bound( maBlockIds.begin(), maBlockIds.end(), nBlockId ); + sal_Int32 nIndex = static_cast< sal_Int32 >( aIt - maBlockIds.begin() ); + + // block id not found in set -> register it now (value of nIndex remains valid) + if( (aIt == maBlockIds.end()) || (*aIt != nBlockId) ) + maBlockIds.insert( aIt, nBlockId ); + + // get one-based offset of shape id in its block + sal_Int32 nBlockOffset = (nShapeId - 1) % 1024 + 1; + + // calculate the local shape index + return 1024 * nIndex + nBlockOffset; +} + const OleObjectInfo* Drawing::getOleObjectInfo( const OUString& rShapeId ) const { return ContainerHelper::getMapElement( maOleObjects, rShapeId ); @@ -142,21 +206,72 @@ const ControlInfo* Drawing::getControlInfo( const OUString& rShapeId ) const return ContainerHelper::getMapElement( maControls, rShapeId ); } +Reference< XShape > Drawing::createAndInsertXShape( const OUString& rService, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const +{ + OSL_ENSURE( rService.getLength() > 0, "Drawing::createAndInsertXShape - missing UNO shape service name" ); + OSL_ENSURE( rxShapes.is(), "Drawing::createAndInsertXShape - missing XShapes container" ); + Reference< XShape > xShape; + if( (rService.getLength() > 0) && rxShapes.is() ) try + { + Reference< XMultiServiceFactory > xFactory( mrFilter.getModelFactory(), UNO_SET_THROW ); + xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); + // insert shape into passed shape collection (maybe drawpage or group shape) + rxShapes->add( xShape ); + xShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); + xShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); + } + catch( Exception& ) + { + } + OSL_ENSURE( xShape.is(), "Drawing::createAndInsertXShape - cannot instanciate shape object" ); + return xShape; +} + +Reference< XShape > Drawing::createAndInsertXControlShape( const ::oox::ole::EmbeddedControl& rControl, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect, sal_Int32& rnCtrlIndex ) const +{ + Reference< XShape > xShape; + try + { + // create control model and insert it into the form of the draw page + Reference< XControlModel > xCtrlModel( getControlForm().convertAndInsert( rControl, rnCtrlIndex ), UNO_SET_THROW ); + + // create the control shape + xShape = createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ), rxShapes, rShapeRect ); + + // set the control model at the shape + Reference< XControlShape >( xShape, UNO_QUERY_THROW )->setControl( xCtrlModel ); + } + catch( Exception& ) + { + } + return xShape; +} + bool Drawing::isShapeSupported( const ShapeBase& /*rShape*/ ) const { return true; } -bool Drawing::convertShapeClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const +OUString Drawing::getShapeBaseName( const ShapeBase& /*rShape*/ ) const +{ + return OUString(); +} + +bool Drawing::convertClientAnchor( Rectangle& /*orShapeRect*/, const OUString& /*rShapeAnchor*/ ) const { return false; } -void Drawing::convertControlClientData( const Reference< XControlModel >& /*rxCtrlModel*/, const ShapeClientData& /*rClientData*/ ) const +Reference< XShape > Drawing::createAndInsertClientXShape( const ShapeBase& /*rShape*/, + const Reference< XShapes >& /*rxShapes*/, const Rectangle& /*rShapeRect*/ ) const { + return Reference< XShape >(); } -void Drawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& /*rShapeRect*/ ) +void Drawing::notifyXShapeInserted( const Reference< XShape >& /*rxShape*/, + const Rectangle& /*rShapeRect*/, const ShapeBase& /*rShape*/, bool /*bGroupChild*/ ) { } diff --git a/oox/source/vml/vmldrawingfragment.cxx b/oox/source/vml/vmldrawingfragment.cxx index 60ed554c2cb6..aaa4532e5328 100644 --- a/oox/source/vml/vmldrawingfragment.cxx +++ b/oox/source/vml/vmldrawingfragment.cxx @@ -47,7 +47,7 @@ using ::rtl::OUString; // ============================================================================ DrawingFragment::DrawingFragment( XmlFilterBase& rFilter, const OUString& rFragmentPath, Drawing& rDrawing ) : - FragmentHandler2( rFilter, rFragmentPath ), + FragmentHandler2( rFilter, rFragmentPath, false ), // do not trim whitespace, has been preprocessed by the input stream mrDrawing( rDrawing ) { } @@ -65,7 +65,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At // DOCX filter handles plain shape elements with this fragment handler case VMLDRAWING_WORD: if( isRootElement() ) - return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); + return ShapeContextBase::createShapeContext( *this, mrDrawing.getShapes(), nElement, rAttribs ); break; // XLSX and PPTX filters load the entire VML fragment @@ -77,7 +77,7 @@ ContextHandlerRef DrawingFragment::onCreateContext( sal_Int32 nElement, const At if( nElement == XML_xml ) return this; break; case XML_xml: - return ShapeContextBase::createShapeContext( *this, nElement, rAttribs, mrDrawing.getShapes() ); + return ShapeContextBase::createShapeContext( *this, mrDrawing.getShapes(), nElement, rAttribs ); } break; } diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index e82f78cf7210..9aa91597dcc9 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -28,14 +28,14 @@ #include "oox/vml/vmlformatting.hxx" #include <rtl/strbuf.hxx> -#include "tokens.hxx" #include "oox/drawingml/color.hxx" #include "oox/drawingml/drawingmltypes.hxx" #include "oox/drawingml/fillproperties.hxx" #include "oox/drawingml/lineproperties.hxx" +#include "oox/helper/attributelist.hxx" #include "oox/helper/graphichelper.hxx" #include "oox/helper/propertymap.hxx" -#include "oox/token/tokenmap.hxx" +#include "tokens.hxx" namespace oox { namespace vml { @@ -85,8 +85,9 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r /*static*/ bool ConversionHelper::decodeBool( const OUString& rValue ) { + sal_Int32 nToken = AttributeConversion::decodeToken( rValue ); // anything else than 't' or 'true' is considered to be false, as specified - return ((rValue.getLength() == 1) && (rValue[ 0 ] == 't')) || (rValue == CREATE_OUSTRING( "true" )); + return (nToken == XML_t) || (nToken == XML_true); } /*static*/ double ConversionHelper::decodePercent( const OUString& rValue, double fDefValue ) @@ -175,58 +176,35 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r return (decodeMeasureToEmu( rGraphicHelper, rValue, nRefValue, bPixelX, bDefaultAsPixel ) + 180) / 360; } -// ============================================================================ - -namespace { - -/** Converts a VML color attribute to a DrawingML color. - - @param orDmlColor (out-parameter) The destination DrawingML color. - - @param roVmlColor The VML string representation of the color. If existing, - this can be a 6-digit hexadecimal RGB value with leading '#' character, - a predefined color name (e.g. 'black', 'red', etc.), the index into an - application defined color palette in brackets with leading color name - (e.g. 'red [9]' or 'windowColor [64]'), or a color modifier used in - one-color gradients (e.g. 'fill darken(128)' or 'fill lighten(0)'. - - @param roVmlOpacity The opacity of the color. If existing, this should be - a floating-point value in the range [0.0;1.0]. - - @param nDefaultRgb Deafult RGB color used if the parameter roVmlColor is - empty. - - @param nPrimaryRgb If set to something else than API_RGB_TRANSPARENT, - specifies the color to be used to resolve the color modifiers used in - one-color gradients. - */ -void lclGetColor( Color& orDmlColor, const GraphicHelper& rGraphicHelper, +/*static*/ Color ConversionHelper::decodeColor( const GraphicHelper& rGraphicHelper, const OptValue< OUString >& roVmlColor, const OptValue< double >& roVmlOpacity, - sal_Int32 nDefaultRgb, sal_Int32 nPrimaryRgb = API_RGB_TRANSPARENT ) + sal_Int32 nDefaultRgb, sal_Int32 nPrimaryRgb ) { + Color aDmlColor; + // convert opacity const sal_Int32 DML_FULL_OPAQUE = ::oox::drawingml::MAX_PERCENT; double fOpacity = roVmlOpacity.get( 1.0 ); sal_Int32 nOpacity = getLimitedValue< sal_Int32, double >( fOpacity * DML_FULL_OPAQUE, 0, DML_FULL_OPAQUE ); if( nOpacity < DML_FULL_OPAQUE ) - orDmlColor.addTransformation( XML_alpha, nOpacity ); + aDmlColor.addTransformation( XML_alpha, nOpacity ); // color attribute not present - set passed default color if( !roVmlColor.has() ) { - orDmlColor.setSrgbClr( nDefaultRgb ); - return; + aDmlColor.setSrgbClr( nDefaultRgb ); + return aDmlColor; } // separate leading color name or RGB value from following palette index OUString aColorName, aColorIndex; - ConversionHelper::separatePair( aColorName, aColorIndex, roVmlColor.get(), ' ' ); + separatePair( aColorName, aColorIndex, roVmlColor.get(), ' ' ); // RGB colors in the format '#RRGGBB' if( (aColorName.getLength() == 7) && (aColorName[ 0 ] == '#') ) { - orDmlColor.setSrgbClr( aColorName.copy( 1 ).toInt32( 16 ) ); - return; + aDmlColor.setSrgbClr( aColorName.copy( 1 ).toInt32( 16 ) ); + return aDmlColor; } // RGB colors in the format '#RGB' @@ -235,27 +213,27 @@ void lclGetColor( Color& orDmlColor, const GraphicHelper& rGraphicHelper, sal_Int32 nR = aColorName.copy( 1, 1 ).toInt32( 16 ) * 0x11; sal_Int32 nG = aColorName.copy( 2, 1 ).toInt32( 16 ) * 0x11; sal_Int32 nB = aColorName.copy( 3, 1 ).toInt32( 16 ) * 0x11; - orDmlColor.setSrgbClr( (nR << 16) | (nG << 8) | nB ); - return; + aDmlColor.setSrgbClr( (nR << 16) | (nG << 8) | nB ); + return aDmlColor; } /* Predefined color names or system color names (resolve to RGB to detect valid color name). */ - sal_Int32 nColorToken = StaticTokenMap::get().getTokenFromUnicode( aColorName ); + sal_Int32 nColorToken = AttributeConversion::decodeToken( aColorName ); sal_Int32 nRgbValue = Color::getVmlPresetColor( nColorToken, API_RGB_TRANSPARENT ); if( nRgbValue == API_RGB_TRANSPARENT ) nRgbValue = rGraphicHelper.getSystemColor( nColorToken, API_RGB_TRANSPARENT ); if( nRgbValue != API_RGB_TRANSPARENT ) { - orDmlColor.setSrgbClr( nRgbValue ); - return; + aDmlColor.setSrgbClr( nRgbValue ); + return aDmlColor; } // try palette colors enclosed in brackets if( (aColorIndex.getLength() >= 3) && (aColorIndex[ 0 ] == '[') && (aColorIndex[ aColorIndex.getLength() - 1 ] == ']') ) { - orDmlColor.setPaletteClr( aColorIndex.copy( 1, aColorIndex.getLength() - 2 ).toInt32() ); - return; + aDmlColor.setPaletteClr( aColorIndex.copy( 1, aColorIndex.getLength() - 2 ).toInt32() ); + return aDmlColor; } // try fill gradient modificator 'fill <modifier>(<amount>)' @@ -266,7 +244,7 @@ void lclGetColor( Color& orDmlColor, const GraphicHelper& rGraphicHelper, if( (2 <= nOpenParen) && (nOpenParen + 1 < nCloseParen) && (nCloseParen + 1 == aColorIndex.getLength()) ) { sal_Int32 nModToken = XML_TOKEN_INVALID; - switch( StaticTokenMap::get().getTokenFromUnicode( aColorIndex.copy( 0, nOpenParen ) ) ) + switch( AttributeConversion::decodeToken( aColorIndex.copy( 0, nOpenParen ) ) ) { case XML_darken: nModToken = XML_shade; case XML_lighten: nModToken = XML_tint; @@ -277,18 +255,23 @@ void lclGetColor( Color& orDmlColor, const GraphicHelper& rGraphicHelper, /* Simulate this modifier color by a color with related transformation. The modifier amount has to be converted from the range [0;255] to percentage [0;100000] used by DrawingML. */ - orDmlColor.setSrgbClr( nPrimaryRgb ); - orDmlColor.addTransformation( nModToken, static_cast< sal_Int32 >( nValue * ::oox::drawingml::MAX_PERCENT / 255 ) ); - return; + aDmlColor.setSrgbClr( nPrimaryRgb ); + aDmlColor.addTransformation( nModToken, static_cast< sal_Int32 >( nValue * ::oox::drawingml::MAX_PERCENT / 255 ) ); + return aDmlColor; } } } - OSL_ENSURE( false, OStringBuffer( "lclGetColor - invalid VML color name '" ). + OSL_ENSURE( false, OStringBuffer( "ConversionHelper::decodeColor - invalid VML color name '" ). append( OUStringToOString( roVmlColor.get(), RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); - orDmlColor.setSrgbClr( nDefaultRgb ); + aDmlColor.setSrgbClr( nDefaultRgb ); + return aDmlColor; } +// ============================================================================ + +namespace { + sal_Int32 lclGetEmu( const GraphicHelper& rGraphicHelper, const OptValue< OUString >& roValue, sal_Int32 nDefValue ) { return roValue.has() ? ConversionHelper::decodeMeasureToEmu( rGraphicHelper, roValue.get(), 0, false, false ) : nDefValue; @@ -299,7 +282,7 @@ void lclGetDmlLineDash( OptValue< sal_Int32 >& oroPresetDash, LineProperties::Da if( roDashStyle.has() ) { const OUString& rDashStyle = roDashStyle.get(); - switch( StaticTokenMap::get().getTokenFromUnicode( rDashStyle ) ) + switch( AttributeConversion::decodeToken( rDashStyle ) ) { case XML_solid: oroPresetDash = XML_solid; return; case XML_shortdot: oroPresetDash = XML_sysDot; return; @@ -445,7 +428,7 @@ void StrokeModel::pushToPropMap( PropertyMap& rPropMap, aLineProps.maLineFill.moFillType = XML_solidFill; lclConvertArrow( aLineProps.maStartArrow, maStartArrow ); lclConvertArrow( aLineProps.maEndArrow, maEndArrow ); - lclGetColor( aLineProps.maLineFill.maFillColor, rGraphicHelper, moColor, moOpacity, API_RGB_BLACK ); + aLineProps.maLineFill.maFillColor = ConversionHelper::decodeColor( rGraphicHelper, moColor, moOpacity, API_RGB_BLACK ); aLineProps.moLineWidth = lclGetEmu( rGraphicHelper, moWeight, 1 ); lclGetDmlLineDash( aLineProps.moPresetDash, aLineProps.maCustomDash, moDashStyle ); aLineProps.moLineCompound = lclGetDmlLineCompound( moLineStyle ); @@ -498,9 +481,8 @@ void FillModel::pushToPropMap( PropertyMap& rPropMap, double fFocus = moFocus.get( 0.0 ); // prepare colors - Color aColor1, aColor2; - lclGetColor( aColor1, rGraphicHelper, moColor, moOpacity, API_RGB_WHITE ); - lclGetColor( aColor2, rGraphicHelper, moColor2, moOpacity2, API_RGB_WHITE, aColor1.getColor( rGraphicHelper ) ); + Color aColor1 = ConversionHelper::decodeColor( rGraphicHelper, moColor, moOpacity, API_RGB_WHITE ); + Color aColor2 = ConversionHelper::decodeColor( rGraphicHelper, moColor2, moOpacity2, API_RGB_WHITE, aColor1.getColor( rGraphicHelper ) ); // type XML_gradient is linear or axial gradient if( nFillType == XML_gradient ) @@ -588,7 +570,7 @@ void FillModel::pushToPropMap( PropertyMap& rPropMap, { aFillProps.moFillType = XML_solidFill; // fill color (default is white) - lclGetColor( aFillProps.maFillColor, rGraphicHelper, moColor, moOpacity, API_RGB_WHITE ); + aFillProps.maFillColor = ConversionHelper::decodeColor( rGraphicHelper, moColor, moOpacity, API_RGB_WHITE ); } } } diff --git a/oox/source/vml/vmlinputstream.cxx b/oox/source/vml/vmlinputstream.cxx index 27776c66ca0b..fb2443aba4c4 100644 --- a/oox/source/vml/vmlinputstream.cxx +++ b/oox/source/vml/vmlinputstream.cxx @@ -151,6 +151,48 @@ void lclProcessAttribs( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal lclAppendToBuffer( rBuffer, pcBeg, pcEnd ); } +void lclProcessContents( OStringBuffer& rBuffer, const sal_Char* pcBeg, const sal_Char* pcEnd ) +{ + /* MSO has a very weird way to store and handle whitespaces. The stream + may contain lots of spaces, tabs, and newlines which have to be handled + as single space character. This will be done in this function. + + If the element text contains a literal line break, it will be stored as + <br> tag (without matching closing </br> element). + + A single space character following another character is stored + literally and must not be stipped away here. Example: The element + <font>abc </font> + contains the three letters a, b, and c, followed by a space character. + + Consecutive space characters, or a leading single space character, are + stored in a <span> element. If there are N space characters (N > 1), + then the <span> element contains exactly (N-1) NBSP characters + (non-breaking space), followed by a regular space character. Example: + The element + <font><span style='mso-spacerun:yes'>\xA0\xA0\xA0 </span></font> + represents 4 consecutive space characters. Has to be handled by the + implementation. + + A single space character for its own is stored in an empty element. + Example: The element + <font></font> + represents a single space character. Has to be handled by the + implementation. + */ + + // skip leading whitespace + const sal_Char* pcContentsBeg = lclFindNonWhiteSpace( pcBeg, pcEnd ); + while( pcContentsBeg < pcEnd ) + { + const sal_Char* pcWhitespaceBeg = lclFindWhiteSpace( pcContentsBeg + 1, pcEnd ); + lclAppendToBuffer( rBuffer, pcContentsBeg, pcWhitespaceBeg ); + if( pcWhitespaceBeg < pcEnd ) + rBuffer.append( ' ' ); + pcContentsBeg = lclFindNonWhiteSpace( pcWhitespaceBeg, pcEnd ); + } +} + } // namespace // ============================================================================ @@ -179,8 +221,9 @@ StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInS { // 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 ); + lclProcessContents( aBuffer, pcCurr, pcOpen ); // nothing to do if no opening bracket has been found if( pcOpen < pcEnd ) @@ -217,10 +260,10 @@ StreamDataContainer::StreamDataContainer( const Reference< XInputStream >& rxInS // do nothing } - // replace '<br>' elements with '<br/>' elements + // replace '<br>' element with newline else if( (nElementLen >= 4) && (pcOpen[ 1 ] == 'b') && (pcOpen[ 2 ] == 'r') && (lclFindNonWhiteSpace( pcOpen + 3, pcClose ) == pcClose) ) { - aBuffer.append( RTL_CONSTASCII_STRINGPARAM( "<br/>" ) ); + aBuffer.append( '\n' ); } // check start elements and empty elements for repeated attributes diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 290e624698f4..5603d1b541b1 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -27,16 +27,14 @@ #include "oox/vml/vmlshape.hxx" -#include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/PropertyValues.hpp> #include <com/sun/star/awt/XControlModel.hpp> #include <com/sun/star/drawing/PointSequenceSequence.hpp> -#include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp> #include <com/sun/star/drawing/XShapes.hpp> #include <com/sun/star/graphic/XGraphic.hpp> #include <rtl/math.hxx> -#include "properties.hxx" +#include <rtl/ustrbuf.hxx> #include "oox/core/xmlfilterbase.hxx" #include "oox/helper/graphichelper.hxx" #include "oox/helper/propertymap.hxx" @@ -46,6 +44,8 @@ #include "oox/ole/oleobjecthelper.hxx" #include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmlshapecontainer.hxx" +#include "oox/vml/vmltextbox.hxx" +#include "properties.hxx" namespace oox { namespace vml { @@ -55,16 +55,21 @@ namespace vml { using namespace ::com::sun::star::awt; using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::graphic; -using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using ::oox::core::XmlFilterBase; using ::rtl::OUString; +using ::rtl::OUStringBuffer; // ============================================================================ namespace { +const sal_Int32 VML_SHAPETYPE_PICTUREFRAME = 75; +const sal_Int32 VML_SHAPETYPE_HOSTCONTROL = 201; + +// ---------------------------------------------------------------------------- + Point lclGetAbsPoint( const Point& rRelPoint, const Rectangle& rShapeRect, const Rectangle& rCoordSys ) { double fWidthRatio = static_cast< double >( rShapeRect.Width ) / rCoordSys.Width; @@ -87,55 +92,6 @@ Rectangle lclGetAbsRect( const Rectangle& rRelRect, const Rectangle& rShapeRect, return aAbsRect; } -Reference< XShape > lclCreateXShape( const XmlFilterBase& rFilter, const OUString& rService ) -{ - OSL_ENSURE( rService.getLength() > 0, "lclCreateXShape - missing UNO shape service name" ); - Reference< XShape > xShape; - try - { - Reference< XMultiServiceFactory > xFactory( rFilter.getModelFactory(), UNO_SET_THROW ); - xShape.set( xFactory->createInstance( rService ), UNO_QUERY_THROW ); - } - catch( Exception& ) - { - } - OSL_ENSURE( xShape.is(), "lclCreateXShape - cannot instanciate shape object" ); - return xShape; -} - -void lclInsertXShape( const Reference< XShapes >& rxShapes, const Reference< XShape >& rxShape ) -{ - OSL_ENSURE( rxShapes.is(), "lclInsertXShape - missing XShapes container" ); - OSL_ENSURE( rxShape.is(), "lclInsertXShape - missing XShape" ); - if( rxShapes.is() && rxShape.is() ) try - { - // insert shape into passed shape collection (maybe drawpage or group shape) - rxShapes->add( rxShape ); - } - catch( Exception& ) - { - } -} - -void lclSetXShapeRect( const Reference< XShape >& rxShape, const Rectangle& rShapeRect ) -{ - OSL_ENSURE( rxShape.is(), "lclSetXShapeRect - missing XShape" ); - if( rxShape.is() ) - { - rxShape->setPosition( Point( rShapeRect.X, rShapeRect.Y ) ); - rxShape->setSize( Size( rShapeRect.Width, rShapeRect.Height ) ); - } -} - -Reference< XShape > lclCreateAndInsertXShape( const XmlFilterBase& rFilter, - const Reference< XShapes >& rxShapes, const OUString& rService, const Rectangle& rShapeRect ) -{ - Reference< XShape > xShape = lclCreateXShape( rFilter, rService ); - lclInsertXShape( rxShapes, xShape ); - lclSetXShapeRect( xShape, rShapeRect ); - return xShape; -} - } // namespace // ============================================================================ @@ -168,6 +124,11 @@ ShapeType::~ShapeType() { } +sal_Int32 ShapeType::getShapeType() const +{ + return maTypeModel.moShapeType.get( 0 ); +} + OUString ShapeType::getGraphicPath() const { return maTypeModel.moGraphicPath.get( OUString() ); @@ -208,12 +169,30 @@ Rectangle ShapeType::getRelRectangle() const // ============================================================================ -ShapeClientData::ShapeClientData() : +ClientData::ClientData() : mnObjType( XML_TOKEN_INVALID ), + mnTextHAlign( XML_Left ), + mnTextVAlign( XML_Top ), mnCol( -1 ), mnRow( -1 ), + mnChecked( VML_CLIENTDATA_UNCHECKED ), + mnDropStyle( XML_Combo ), + mnDropLines( 1 ), + mnVal( 0 ), + mnMin( 0 ), + mnMax( 0 ), + mnInc( 0 ), + mnPage( 0 ), + mnSelType( XML_Single ), + mnVTEdit( VML_CLIENTDATA_TEXT ), mbPrintObject( true ), - mbVisible( false ) + mbVisible( false ), + mbDde( false ), + mbNo3D( false ), + mbNo3D2( false ), + mbMultiLine( false ), + mbVScroll( false ), + mbSecretEdit( false ) { } @@ -223,9 +202,19 @@ ShapeModel::ShapeModel() { } -ShapeClientData& ShapeModel::createClientData() +ShapeModel::~ShapeModel() +{ +} + +TextBox& ShapeModel::createTextBox() +{ + mxTextBox.reset( new TextBox ); + return *mxTextBox; +} + +ClientData& ShapeModel::createClientData() { - mxClientData.reset( new ShapeClientData ); + mxClientData.reset( new ClientData ); return *mxClientData; } @@ -244,6 +233,22 @@ void ShapeBase::finalizeFragmentImport() maTypeModel.assignUsed( pShapeType->getTypeModel() ); } +OUString ShapeBase::getShapeName() const +{ + if( maTypeModel.maShapeName.getLength() > 0 ) + return maTypeModel.maShapeName; + + OUString aBaseName = mrDrawing.getShapeBaseName( *this ); + if( aBaseName.getLength() > 0 ) + { + sal_Int32 nShapeIdx = mrDrawing.getLocalShapeIndex( getShapeId() ); + if( nShapeIdx > 0 ) + return OUStringBuffer( aBaseName ).append( sal_Unicode( ' ' ) ).append( nShapeIdx ).makeStringAndClear(); + } + + return OUString(); +} + const ShapeType* ShapeBase::getChildTypeById( const OUString& ) const { return 0; @@ -262,15 +267,23 @@ Reference< XShape > ShapeBase::convertAndInsert( const Reference< XShapes >& rxS /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ 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 ); + if( xShape.is() ) + { + // set shape name (imported or generated) + PropertySet aShapeProp( xShape ); + aShapeProp.setProperty( PROP_Name, getShapeName() ); + + /* Notify the drawing that a new shape has been inserted. For + convenience, pass the rectangle that contains position and + size of the shape. */ + bool bGroupChild = pParentAnchor != 0; + mrDrawing.notifyXShapeInserted( xShape, aShapeRect, *this, bGroupChild ); + } } } return xShape; @@ -283,10 +296,12 @@ void ShapeBase::convertFormatting( const Reference< XShape >& rxShape, const Sha /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ Rectangle aShapeRect = calcShapeRectangle( pParentAnchor ); + // convert the shape, if the calculated rectangle is not empty if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) ) { - lclSetXShapeRect( rxShape, aShapeRect ); + rxShape->setPosition( Point( aShapeRect.X, aShapeRect.Y ) ); + rxShape->setSize( Size( aShapeRect.Width, aShapeRect.Height ) ); convertShapeProperties( rxShape ); } } @@ -299,7 +314,8 @@ Rectangle ShapeBase::calcShapeRectangle( const ShapeParentAnchor* pParentAnchor /* Calculate shape rectangle. Applications may do something special according to some imported shape client data (e.g. Excel cell anchor). */ Rectangle aShapeRect; - if( !maShapeModel.mxClientData.get() || !mrDrawing.convertShapeClientAnchor( aShapeRect, maShapeModel.mxClientData->maAnchor ) ) + const ClientData* pClientData = getClientData(); + if( !pClientData || !mrDrawing.convertClientAnchor( aShapeRect, pClientData->maAnchor ) ) aShapeRect = getRectangle( pParentAnchor ); return aShapeRect; } @@ -327,7 +343,7 @@ SimpleShape::SimpleShape( Drawing& rDrawing, const OUString& rService ) : Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - Reference< XShape > xShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, maService, rShapeRect ); + Reference< XShape > xShape = mrDrawing.createAndInsertXShape( maService, rxShapes, rShapeRect ); convertShapeProperties( xShape ); return xShape; } @@ -386,7 +402,7 @@ Reference< XShape > CustomShape::implConvertAndInsert( const Reference< XShapes { // create the custom shape geometry Reference< XEnhancedCustomShapeDefaulter > xDefaulter( xShape, UNO_QUERY_THROW ); - xDefaulter->createCustomShapeDefaults( OUString::valueOf( maTypeModel.moShapeType.get( 0 ) ) ); + xDefaulter->createCustomShapeDefaults( OUString::valueOf( getShapeType() ) ); // convert common properties convertShapeProperties( xShape ); } @@ -406,11 +422,14 @@ ComplexShape::ComplexShape( Drawing& rDrawing ) : Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { XmlFilterBase& rFilter = mrDrawing.getFilter(); + sal_Int32 nShapeType = getShapeType(); OUString aGraphicPath = getGraphicPath(); // try to find registered OLE object info if( const OleObjectInfo* pOleObjectInfo = mrDrawing.getOleObjectInfo( maTypeModel.maShapeId ) ) { + OSL_ENSURE( nShapeType == VML_SHAPETYPE_PICTUREFRAME, "ComplexShape::implConvertAndInsert - unexpected shape type" ); + // if OLE object is embedded into a DrawingML shape (PPTX), do not create it here if( pOleObjectInfo->mbDmlShape ) return Reference< XShape >(); @@ -419,7 +438,7 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes Size aOleSize( rShapeRect.Width, rShapeRect.Height ); if( rFilter.getOleObjectHelper().importOleObject( aOleProps, *pOleObjectInfo, aOleSize ) ) { - Reference< XShape > xShape = lclCreateAndInsertXShape( rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rShapeRect ); + Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.OLE2Shape" ), rxShapes, rShapeRect ); if( xShape.is() ) { // set the replacement graphic @@ -440,36 +459,40 @@ Reference< XShape > ComplexShape::implConvertAndInsert( const Reference< XShapes // try to find registered form control info const ControlInfo* pControlInfo = mrDrawing.getControlInfo( maTypeModel.maShapeId ); - if( pControlInfo && (pControlInfo->maFragmentPath.getLength() > 0) && (maTypeModel.maName.getLength() > 0) ) + if( pControlInfo && (pControlInfo->maFragmentPath.getLength() > 0) ) { - OSL_ENSURE( maTypeModel.maName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" ); - ::oox::ole::EmbeddedControl aControl( maTypeModel.maName ); - // load the control properties from fragment - if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) ) try - { - // create control model and insert it into the form of the draw page - Reference< XControlModel > xCtrlModel( mrDrawing.getControlForm().convertAndInsert( aControl ), UNO_SET_THROW ); - if( maShapeModel.mxClientData.get() ) - mrDrawing.convertControlClientData( xCtrlModel, *maShapeModel.mxClientData ); - - // create the control shape, set control model at the shape - Reference< XShape > xShape = lclCreateAndInsertXShape( - rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ), rShapeRect ); - Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY ); // do not throw, but always return the shape - if( xCtrlShape.is() ) - xCtrlShape->setControl( xCtrlModel ); - return xShape; - } - catch( Exception& ) + OSL_ENSURE( nShapeType == VML_SHAPETYPE_HOSTCONTROL, "ComplexShape::implConvertAndInsert - unexpected shape type" ); + OUString aShapeName = getShapeName(); + if( aShapeName.getLength() > 0 ) { + OSL_ENSURE( aShapeName == pControlInfo->maName, "ComplexShape::implConvertAndInsert - control name mismatch" ); + // load the control properties from fragment + ::oox::ole::EmbeddedControl aControl( aShapeName ); + if( rFilter.importFragment( new ::oox::ole::AxControlFragment( rFilter, pControlInfo->maFragmentPath, aControl ) ) ) + { + // create and return the control shape (including control model) + sal_Int32 nCtrlIndex = -1; + Reference< XShape > xShape = mrDrawing.createAndInsertXControlShape( aControl, rxShapes, rShapeRect, nCtrlIndex ); + // on error, proceed and try to create picture from replacement image + if( xShape.is() ) + return xShape; + } } - // on error, proceed and try to create picture from replacement image + } + + // host application wants to create the shape (do not try failed OLE controls again) + if( (nShapeType == VML_SHAPETYPE_HOSTCONTROL) && !pControlInfo ) + { + OSL_ENSURE( getClientData(), "ComplexShape::implConvertAndInsert - missing client data" ); + Reference< XShape > xShape = mrDrawing.createAndInsertClientXShape( *this, rxShapes, rShapeRect ); + if( xShape.is() ) + return xShape; } // try to create a picture object if( aGraphicPath.getLength() > 0 ) { - Reference< XShape > xShape = lclCreateAndInsertXShape( rFilter, rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rShapeRect ); + Reference< XShape > xShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GraphicObjectShape" ), rxShapes, rShapeRect ); if( xShape.is() ) { OUString aGraphicUrl = rFilter.getGraphicHelper().importEmbeddedGraphicObject( aGraphicPath ); @@ -525,7 +548,7 @@ Reference< XShape > GroupShape::implConvertAndInsert( const Reference< XShapes > aParentAnchor.maCoordSys = getCoordSystem(); if( !mxChildren->empty() && (aParentAnchor.maCoordSys.Width > 0) && (aParentAnchor.maCoordSys.Height > 0) ) try { - xGroupShape = lclCreateAndInsertXShape( mrDrawing.getFilter(), rxShapes, CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rShapeRect ); + xGroupShape = mrDrawing.createAndInsertXShape( CREATE_OUSTRING( "com.sun.star.drawing.GroupShape" ), rxShapes, rShapeRect ); Reference< XShapes > xChildShapes( xGroupShape, UNO_QUERY_THROW ); mxChildren->convertAndInsert( xChildShapes, &aParentAnchor ); // no child shape has been created - delete the group shape diff --git a/oox/source/vml/vmlshapecontext.cxx b/oox/source/vml/vmlshapecontext.cxx index ac08c1836c2d..d16644a7908a 100644 --- a/oox/source/vml/vmlshapecontext.cxx +++ b/oox/source/vml/vmlshapecontext.cxx @@ -27,8 +27,10 @@ #include "oox/vml/vmlshapecontext.hxx" +#include "oox/vml/vmldrawing.hxx" #include "oox/vml/vmlshape.hxx" #include "oox/vml/vmlshapecontainer.hxx" +#include "oox/vml/vmltextboxcontext.hxx" namespace oox { namespace vml { @@ -104,39 +106,101 @@ OptValue< DoublePair > lclDecodePercentPair( const AttributeList& rAttribs, sal_ bool lclDecodeVmlxBool( const OUString& rValue, bool bDefaultForEmpty ) { if( rValue.getLength() == 0 ) return bDefaultForEmpty; + sal_Int32 nToken = AttributeConversion::decodeToken( rValue ); // anything else than 't' or 'True' is considered to be false, as specified - return ((rValue.getLength() == 1) && (rValue[ 0 ] == 't')) || (rValue == CREATE_OUSTRING( "True" )); + return (nToken == XML_t) || (nToken == XML_True); } } // namespace // ============================================================================ -ShapeClientDataContext::ShapeClientDataContext( ContextHandler2Helper& rParent, - const AttributeList& rAttribs, ShapeClientData& rClientData ) : +ShapeLayoutContext::ShapeLayoutContext( ContextHandler2Helper& rParent, Drawing& rDrawing ) : + ContextHandler2( rParent ), + mrDrawing( rDrawing ) +{ +} + + +ContextHandlerRef ShapeLayoutContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( nElement ) + { + case O_TOKEN( idmap ): + { + OUString aBlockIds = rAttribs.getString( XML_data, OUString() ); + sal_Int32 nIndex = 0; + while( nIndex >= 0 ) + { + OUString aToken = aBlockIds.getToken( 0, ' ', nIndex ).trim(); + if( aToken.getLength() > 0 ) + mrDrawing.registerBlockId( aToken.toInt32() ); + } + } + break; + } + return 0; +} + +// ============================================================================ + +ClientDataContext::ClientDataContext( ContextHandler2Helper& rParent, + ClientData& rClientData, const AttributeList& rAttribs ) : ContextHandler2( rParent ), mrClientData( rClientData ) { mrClientData.mnObjType = rAttribs.getToken( XML_ObjectType, XML_TOKEN_INVALID ); } -ContextHandlerRef ShapeClientDataContext::onCreateContext( sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ ) +ContextHandlerRef ClientDataContext::onCreateContext( sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ ) { - return isRootElement() ? this : 0; + if( isRootElement() ) + { + maElementText = OUString(); + return this; + } + return 0; } -void ShapeClientDataContext::onEndElement( const OUString& rChars ) +void ClientDataContext::onCharacters( const OUString& rChars ) +{ + /* Empty but existing elements have special meaning, e.g. 'true'. Collect + existing text and convert it in onEndElement(). */ + maElementText = rChars; +} + +void ClientDataContext::onEndElement() { switch( getCurrentElement() ) { - case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = rChars; break; - case VMLX_TOKEN( FmlaPict ): mrClientData.maPictureLink = rChars; break; - case VMLX_TOKEN( FmlaLink ): mrClientData.maLinkedCell = rChars; break; - case VMLX_TOKEN( FmlaRange ): mrClientData.maSourceRange = rChars; break; - case VMLX_TOKEN( Column ): mrClientData.mnCol = rChars.toInt32(); break; - case VMLX_TOKEN( Row ): mrClientData.mnRow = rChars.toInt32(); break; - case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeVmlxBool( rChars, true ); break; - case VMLX_TOKEN( Visible ): mrClientData.mbVisible = true; break; + case VMLX_TOKEN( Anchor ): mrClientData.maAnchor = maElementText; break; + case VMLX_TOKEN( FmlaMacro ): mrClientData.maFmlaMacro = maElementText; break; + case VMLX_TOKEN( FmlaPict ): mrClientData.maFmlaPict = maElementText; break; + case VMLX_TOKEN( FmlaLink ): mrClientData.maFmlaLink = maElementText; break; + case VMLX_TOKEN( FmlaRange ): mrClientData.maFmlaRange = maElementText; break; + case VMLX_TOKEN( FmlaGroup ): mrClientData.maFmlaGroup = maElementText; break; + case VMLX_TOKEN( TextHAlign ): mrClientData.mnTextHAlign = AttributeConversion::decodeToken( maElementText ); break; + case VMLX_TOKEN( TextVAlign ): mrClientData.mnTextVAlign = AttributeConversion::decodeToken( maElementText ); break; + case VMLX_TOKEN( Column ): mrClientData.mnCol = maElementText.toInt32(); break; + case VMLX_TOKEN( Row ): mrClientData.mnRow = maElementText.toInt32(); break; + case VMLX_TOKEN( Checked ): mrClientData.mnChecked = maElementText.toInt32(); break; + case VMLX_TOKEN( DropStyle ): mrClientData.mnDropStyle = AttributeConversion::decodeToken( maElementText ); break; + case VMLX_TOKEN( DropLines ): mrClientData.mnDropLines = maElementText.toInt32(); break; + case VMLX_TOKEN( Val ): mrClientData.mnVal = maElementText.toInt32(); break; + case VMLX_TOKEN( Min ): mrClientData.mnMin = maElementText.toInt32(); break; + case VMLX_TOKEN( Max ): mrClientData.mnMax = maElementText.toInt32(); break; + case VMLX_TOKEN( Inc ): mrClientData.mnInc = maElementText.toInt32(); break; + case VMLX_TOKEN( Page ): mrClientData.mnPage = maElementText.toInt32(); break; + case VMLX_TOKEN( SelType ): mrClientData.mnSelType = AttributeConversion::decodeToken( maElementText ); break; + case VMLX_TOKEN( VTEdit ): mrClientData.mnVTEdit = maElementText.toInt32(); break; + case VMLX_TOKEN( PrintObject ): mrClientData.mbPrintObject = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( Visible ): mrClientData.mbVisible = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( DDE ): mrClientData.mbDde = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( NoThreeD ): mrClientData.mbNo3D = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( NoThreeD2 ): mrClientData.mbNo3D2 = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( MultiLine ): mrClientData.mbMultiLine = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( VScroll ): mrClientData.mbVScroll = lclDecodeVmlxBool( maElementText, true ); break; + case VMLX_TOKEN( SecretEdit ): mrClientData.mbSecretEdit = lclDecodeVmlxBool( maElementText, true ); break; } } @@ -148,23 +212,26 @@ ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) : } /*static*/ ContextHandlerRef ShapeContextBase::createShapeContext( ContextHandler2Helper& rParent, - sal_Int32 nElement, const AttributeList& rAttribs, ShapeContainer& rShapes ) + ShapeContainer& rShapes, sal_Int32 nElement, const AttributeList& rAttribs ) { switch( nElement ) { + case O_TOKEN( shapelayout ): + return new ShapeLayoutContext( rParent, rShapes.getDrawing() ); + case VML_TOKEN( shapetype ): - return new ShapeTypeContext( rParent, rAttribs, rShapes.createShapeType() ); + return new ShapeTypeContext( rParent, rShapes.createShapeType(), rAttribs ); case VML_TOKEN( group ): - return new GroupShapeContext( rParent, rAttribs, rShapes.createShape< GroupShape >() ); + return new GroupShapeContext( rParent, rShapes.createShape< GroupShape >(), rAttribs ); case VML_TOKEN( shape ): - return new ShapeContext( rParent, rAttribs, rShapes.createShape< ComplexShape >() ); + return new ShapeContext( rParent, rShapes.createShape< ComplexShape >(), rAttribs ); case VML_TOKEN( rect ): case VML_TOKEN( roundrect ): - return new ShapeContext( rParent, rAttribs, rShapes.createShape< RectangleShape >() ); + return new ShapeContext( rParent, rShapes.createShape< RectangleShape >(), rAttribs ); case VML_TOKEN( oval ): - return new ShapeContext( rParent, rAttribs, rShapes.createShape< EllipseShape >() ); + return new ShapeContext( rParent, rShapes.createShape< EllipseShape >(), rAttribs ); case VML_TOKEN( polyline ): - return new ShapeContext( rParent, rAttribs, rShapes.createShape< PolyLineShape >() ); + return new ShapeContext( rParent, rShapes.createShape< PolyLineShape >(), rAttribs ); // TODO: case VML_TOKEN( arc ): @@ -172,14 +239,14 @@ ShapeContextBase::ShapeContextBase( ContextHandler2Helper& rParent ) : case VML_TOKEN( line ): case VML_TOKEN( diagram ): case VML_TOKEN( image ): - return new ShapeContext( rParent, rAttribs, rShapes.createShape< ComplexShape >() ); + return new ShapeContext( rParent, rShapes.createShape< ComplexShape >(), rAttribs ); } return false; } // ============================================================================ -ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, ShapeType& rShapeType ) : +ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, ShapeType& rShapeType, const AttributeList& rAttribs ) : ShapeContextBase( rParent ), mrTypeModel( rShapeType.getTypeModel() ) { @@ -189,7 +256,7 @@ ShapeTypeContext::ShapeTypeContext( ContextHandler2Helper& rParent, const Attrib OSL_ENSURE( mrTypeModel.maShapeId.getLength() > 0, "ShapeTypeContext::ShapeTypeContext - missing shape identifier" ); // if the o:spid attribute exists, the id attribute contains the user-defined shape name if( bHasOspid ) - mrTypeModel.maName = rAttribs.getXString( XML_id, OUString() ); + mrTypeModel.maShapeName = rAttribs.getXString( XML_id, OUString() ); // builtin shape type identifier mrTypeModel.moShapeType = rAttribs.getInteger( O_TOKEN( spt ) ); @@ -280,8 +347,8 @@ void ShapeTypeContext::setStyle( const OUString& rStyle ) // ============================================================================ -ShapeContext::ShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, ShapeBase& rShape ) : - ShapeTypeContext( rParent, rAttribs, rShape ), +ShapeContext::ShapeContext( ContextHandler2Helper& rParent, ShapeBase& rShape, const AttributeList& rAttribs ) : + ShapeTypeContext( rParent, rShape, rAttribs ), mrShapeModel( rShape.getShapeModel() ) { // collect shape specific attributes @@ -293,8 +360,13 @@ ShapeContext::ShapeContext( ContextHandler2Helper& rParent, const AttributeList& ContextHandlerRef ShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { // Excel specific shape client data - if( isRootElement() && (nElement == VMLX_TOKEN( ClientData )) ) - return new ShapeClientDataContext( *this, rAttribs, mrShapeModel.createClientData() ); + if( isRootElement() ) switch( nElement ) + { + case VML_TOKEN( textbox ): + return new TextBoxContext( *this, mrShapeModel.createTextBox(), rAttribs ); + case VMLX_TOKEN( ClientData ): + return new ClientDataContext( *this, mrShapeModel.createClientData(), rAttribs ); + } // handle remaining stuff in base class return ShapeTypeContext::onCreateContext( nElement, rAttribs ); } @@ -313,8 +385,8 @@ void ShapeContext::setPoints( const OUString& rPoints ) // ============================================================================ -GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, const AttributeList& rAttribs, GroupShape& rShape ) : - ShapeContext( rParent, rAttribs, rShape ), +GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, GroupShape& rShape, const AttributeList& rAttribs ) : + ShapeContext( rParent, rShape, rAttribs ), mrShapes( rShape.getChildren() ) { } @@ -322,7 +394,7 @@ GroupShapeContext::GroupShapeContext( ContextHandler2Helper& rParent, const Attr ContextHandlerRef GroupShapeContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) { // try to create a context of an embedded shape - ContextHandlerRef xContext = createShapeContext( *this, nElement, rAttribs, mrShapes ); + ContextHandlerRef xContext = createShapeContext( *this, mrShapes, nElement, rAttribs ); // handle remaining stuff of this shape in base class return xContext.get() ? xContext : ShapeContext::onCreateContext( nElement, rAttribs ); } diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx new file mode 100755 index 000000000000..e684490f39af --- /dev/null +++ b/oox/source/vml/vmltextbox.cxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/vml/vmltextbox.hxx" + +#include <rtl/ustrbuf.hxx> +#include "tokens.hxx" + +namespace oox { +namespace vml { + +// ============================================================================ + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +// ============================================================================ + +TextFontModel::TextFontModel() +{ +} + +// ============================================================================ + +TextPortionModel::TextPortionModel( const TextFontModel& rFont, const OUString& rText ) : + maFont( rFont ), + maText( rText ) +{ +} + +// ============================================================================ + +TextBox::TextBox() +{ +} + +void TextBox::appendPortion( const TextFontModel& rFont, const OUString& rText ) +{ + maPortions.push_back( TextPortionModel( rFont, rText ) ); +} + +const TextFontModel* TextBox::getFirstFont() const +{ + return maPortions.empty() ? 0 : &maPortions.front().maFont; +} + +OUString TextBox::getText() const +{ + OUStringBuffer aBuffer; + for( PortionVector::const_iterator aIt = maPortions.begin(), aEnd = maPortions.end(); aIt != aEnd; ++aIt ) + aBuffer.append( aIt->maText ); + return aBuffer.makeStringAndClear(); +} + +// ============================================================================ + +} // namespace vml +} // namespace oox diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx new file mode 100755 index 000000000000..4b57656b4f78 --- /dev/null +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "oox/vml/vmltextboxcontext.hxx" + +namespace oox { +namespace vml { + +// ============================================================================ + +using ::oox::core::ContextHandler2; +using ::oox::core::ContextHandler2Helper; +using ::oox::core::ContextHandlerRef; +using ::rtl::OUString; + +// ============================================================================ + +TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent, + TextBox& rTextBox, const TextFontModel& rParentFont, + sal_Int32 nElement, const AttributeList& rAttribs ) : + ContextHandler2( rParent ), + mrTextBox( rTextBox ), + maFont( rParentFont ), + mnInitialPortions( rTextBox.getPortionCount() ) +{ + switch( nElement ) + { + case XML_font: + maFont.moName = rAttribs.getXString( XML_face ); + maFont.moColor = rAttribs.getXString( XML_color ); + maFont.monSize = rAttribs.getInteger( XML_size ); + break; + case XML_u: + OSL_ENSURE( !maFont.monUnderline, "TextPortionContext::TextPortionContext - nested <u> elements" ); + maFont.monUnderline = (rAttribs.getToken( XML_class, XML_TOKEN_INVALID ) == XML_font4) ? XML_double : XML_single; + break; + case XML_sub: + case XML_sup: + OSL_ENSURE( !maFont.monEscapement, "TextPortionContext::TextPortionContext - nested <sub> or <sup> elements" ); + maFont.monEscapement = nElement; + break; + case XML_b: + OSL_ENSURE( !maFont.mobBold, "TextPortionContext::TextPortionContext - nested <b> elements" ); + maFont.mobBold = true; + break; + case XML_i: + OSL_ENSURE( !maFont.mobItalic, "TextPortionContext::TextPortionContext - nested <i> elements" ); + maFont.mobItalic = true; + break; + case XML_s: + OSL_ENSURE( !maFont.mobStrikeout, "TextPortionContext::TextPortionContext - nested <s> elements" ); + maFont.mobStrikeout = true; + break; + default: + OSL_ENSURE( false, "TextPortionContext::TextPortionContext - unknown element" ); + } +} + +ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" ); + return new TextPortionContext( *this, mrTextBox, maFont, nElement, rAttribs ); +} + +void TextPortionContext::onCharacters( const OUString& rChars ) +{ + switch( getCurrentElement() ) + { + case XML_span: + // replace all NBSP characters with SP + mrTextBox.appendPortion( maFont, rChars.replace( 160, ' ' ) ); + break; + default: + mrTextBox.appendPortion( maFont, rChars ); + } +} + +void TextPortionContext::onEndElement() +{ + /* An empty child element without own child elements represents a single + space character, for example: + + <font> + <i>abc</i> + <font></font> + <b>def</b> + </font> + + represents the italic text 'abc', an unformatted space character, and + the bold text 'def'. + */ + if( (mnInitialPortions > 0) && (mrTextBox.getPortionCount() == mnInitialPortions) ) + mrTextBox.appendPortion( maFont, OUString( sal_Unicode( ' ' ) ) ); +} + +// ============================================================================ + +TextBoxContext::TextBoxContext( ContextHandler2Helper& rParent, TextBox& rTextBox, const AttributeList& /*rAttribs*/ ) : + ContextHandler2( rParent ), + mrTextBox( rTextBox ) +{ +} + +ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( getCurrentElement() ) + { + case VML_TOKEN( textbox ): + if( nElement == XML_div ) return this; + break; + case XML_div: + if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs ); + break; + } + return 0; +} + +// ============================================================================ + +} // namespace vml +} // namespace oox + diff --git a/oox/source/xls/autofiltercontext.cxx b/oox/source/xls/autofiltercontext.cxx index 4ae31fc94c56..279b62de2ccf 100644 --- a/oox/source/xls/autofiltercontext.cxx +++ b/oox/source/xls/autofiltercontext.cxx @@ -204,7 +204,7 @@ void OoxAutoFilterContext::onStartElement( const AttributeList& rAttribs ) } } -void OoxAutoFilterContext::onEndElement( const OUString& /*rChars*/ ) +void OoxAutoFilterContext::onEndElement() { switch( getCurrentElement() ) { diff --git a/oox/source/xls/chartsheetfragment.cxx b/oox/source/xls/chartsheetfragment.cxx index fe1cdfa179bb..432b50b075f2 100644 --- a/oox/source/xls/chartsheetfragment.cxx +++ b/oox/source/xls/chartsheetfragment.cxx @@ -86,14 +86,14 @@ ContextHandlerRef OoxChartsheetFragment::onCreateContext( sal_Int32 nElement, co case XLS_TOKEN( oddHeader ): case XLS_TOKEN( oddFooter ): case XLS_TOKEN( evenHeader ): - case XLS_TOKEN( evenFooter ): return this; // collect contents in onEndElement() + case XLS_TOKEN( evenFooter ): return this; // collect contents in onCharacters() } break; } return 0; } -void OoxChartsheetFragment::onEndElement( const OUString& rChars ) +void OoxChartsheetFragment::onCharacters( const OUString& rChars ) { switch( getCurrentElement() ) { diff --git a/oox/source/xls/commentsbuffer.cxx b/oox/source/xls/commentsbuffer.cxx index 190309649789..ecc5d4dff390 100644 --- a/oox/source/xls/commentsbuffer.cxx +++ b/oox/source/xls/commentsbuffer.cxx @@ -115,9 +115,8 @@ void Comment::finalizeImport() // position and formatting pNoteShape->convertFormatting( xAnnoShape ); // visibility - const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = pNoteShape->getShapeModel().mxClientData; - bool bVisible = rxClientData.get() && rxClientData->mbVisible; - xAnno->setIsVisible( bVisible ); + const ::oox::vml::ClientData* pClientData = pNoteShape->getClientData(); + xAnno->setIsVisible( pClientData && pClientData->mbVisible ); } } } diff --git a/oox/source/xls/commentsfragment.cxx b/oox/source/xls/commentsfragment.cxx index c87d3028b7cb..44ae98ca7b43 100644 --- a/oox/source/xls/commentsfragment.cxx +++ b/oox/source/xls/commentsfragment.cxx @@ -56,7 +56,7 @@ ContextHandlerRef OoxCommentsFragment::onCreateContext( sal_Int32 nElement, cons if( nElement == XLS_TOKEN( commentList ) ) return this; break; case XLS_TOKEN( authors ): - if( nElement == XLS_TOKEN( author ) ) return this; // collect author in onEndElement() + if( nElement == XLS_TOKEN( author ) ) return this; // collect author in onCharacters() break; case XLS_TOKEN( commentList ): if( nElement == XLS_TOKEN( comment ) ) { importComment( rAttribs ); return this; } @@ -69,17 +69,16 @@ ContextHandlerRef OoxCommentsFragment::onCreateContext( sal_Int32 nElement, cons return 0; } -void OoxCommentsFragment::onEndElement( const OUString& rChars ) +void OoxCommentsFragment::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) - { - case XLS_TOKEN( author ): - getComments().appendAuthor( rChars ); - break; - case XLS_TOKEN( comment ): - mxComment.reset(); - break; - } + if( isCurrentElement( XLS_TOKEN( author ) ) ) + getComments().appendAuthor( rChars ); +} + +void OoxCommentsFragment::onEndElement() +{ + if( isCurrentElement( XLS_TOKEN( comment ) ) ) + mxComment.reset(); } ContextHandlerRef OoxCommentsFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ) @@ -109,12 +108,8 @@ ContextHandlerRef OoxCommentsFragment::onCreateRecordContext( sal_Int32 nRecId, void OoxCommentsFragment::onEndRecord() { - switch( getCurrentElement() ) - { - case OOBIN_ID_COMMENT: - mxComment.reset(); - break; - } + if( isCurrentElement( OOBIN_ID_COMMENT ) ) + mxComment.reset(); } // oox.core.FragmentHandler2 interface ---------------------------------------- diff --git a/oox/source/xls/condformatcontext.cxx b/oox/source/xls/condformatcontext.cxx index 8cd3a33615fc..a879dcb2e86d 100644 --- a/oox/source/xls/condformatcontext.cxx +++ b/oox/source/xls/condformatcontext.cxx @@ -67,14 +67,10 @@ void OoxCondFormatContext::onStartElement( const AttributeList& rAttribs ) } } -void OoxCondFormatContext::onEndElement( const OUString& rChars ) +void OoxCondFormatContext::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) - { - case XLS_TOKEN( formula ): - if( mxCondFmt.get() && mxRule.get() ) mxRule->appendFormula( rChars ); - break; - } + if( isCurrentElement( XLS_TOKEN( formula ) ) && mxCondFmt.get() && mxRule.get() ) + mxRule->appendFormula( rChars ); } ContextHandlerRef OoxCondFormatContext::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& ) diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 7b52b986750a..9f565868a77a 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -27,11 +27,15 @@ #include "oox/xls/drawingfragment.hxx" -#include <com/sun/star/awt/Point.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/document/XEventsSupplier.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/XEventAttacherManager.hpp> +#include <rtl/strbuf.hxx> #include "oox/drawingml/connectorshapecontext.hxx" #include "oox/drawingml/graphicshapecontext.hxx" -#include "oox/drawingml/shapecontext.hxx" -#include "oox/drawingml/shapegroupcontext.hxx" #include "oox/helper/attributelist.hxx" #include "oox/helper/propertyset.hxx" #include "oox/vml/vmlshape.hxx" @@ -48,22 +52,26 @@ namespace xls { // ============================================================================ using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::document; using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::script; using namespace ::com::sun::star::table; using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::oox::core; +using namespace ::oox::drawingml; +using namespace ::oox::ole; -using ::oox::core::ContextHandlerRef; -using ::oox::drawingml::ConnectorShapeContext; -using ::oox::drawingml::GraphicalObjectFrameContext; -using ::oox::drawingml::GraphicShapeContext; -using ::oox::drawingml::Shape; -using ::oox::drawingml::ShapePtr; -using ::oox::drawingml::ShapeContext; -using ::oox::drawingml::ShapeGroupContext; +using ::rtl::OStringBuffer; using ::rtl::OUString; +using ::rtl::OUStringToOString; // no using's for ::oox::vml, that may clash with ::oox::drawingml types // ============================================================================ +// DrawingML +// ============================================================================ namespace { @@ -403,6 +411,108 @@ Rectangle ShapeAnchor::calcEmuLocation( const AnchorSizeModel& rEmuSheetSize ) c // ============================================================================ +ShapeMacroAttacher::ShapeMacroAttacher( const OUString& rMacroName, const Reference< XShape >& rxShape ) : + VbaMacroAttacherBase( rMacroName ), + mxShape( rxShape ) +{ +} + +void ShapeMacroAttacher::attachMacro( const OUString& rMacroUrl ) +{ + try + { + Reference< XEventsSupplier > xSupplier( mxShape, UNO_QUERY_THROW ); + Reference< XNameReplace > xEvents( xSupplier->getEvents(), UNO_SET_THROW ); + Sequence< PropertyValue > aEventProps( 2 ); + aEventProps[ 0 ].Name = CREATE_OUSTRING( "EventType" ); + aEventProps[ 0 ].Value <<= CREATE_OUSTRING( "Script" ); + aEventProps[ 1 ].Name = CREATE_OUSTRING( "Script" ); + aEventProps[ 1 ].Value <<= rMacroUrl; + xEvents->replaceByName( CREATE_OUSTRING( "OnClick" ), Any( aEventProps ) ); + } + catch( Exception& ) + { + } +} + +// ============================================================================ + +Shape::Shape( const WorksheetHelper& rHelper, const AttributeList& rAttribs, const sal_Char* pcServiceName ) : + ::oox::drawingml::Shape( pcServiceName ), + WorksheetHelper( rHelper ) +{ + OUString aMacro = rAttribs.getXString( XML_macro, OUString() ); + if( aMacro.getLength() > 0 ) + maMacroName = getFormulaParser().importMacroName( aMacro ); +} + +void Shape::finalizeXShape( XmlFilterBase& rFilter, const Reference< XShapes >& rxShapes ) +{ + if( (maMacroName.getLength() > 0) && mxShape.is() ) + { + VbaMacroAttacherRef xAttacher( new ShapeMacroAttacher( maMacroName, mxShape ) ); + getBaseFilter().getVbaProject().registerMacroAttacher( xAttacher ); + } + ::oox::drawingml::Shape::finalizeXShape( rFilter, rxShapes ); +} + +// ============================================================================ + +OoxGroupShapeContext::OoxGroupShapeContext( ContextHandler& rParent, + const WorksheetHelper& rHelper, const ShapePtr& rxShape ) : + ShapeGroupContext( rParent, ShapePtr(), rxShape ), + WorksheetHelper( rHelper ) +{ +} + +/*static*/ ContextHandlerRef OoxGroupShapeContext::createShapeContext( ContextHandler& rParent, + const WorksheetHelper& rHelper, sal_Int32 nElement, const AttributeList& rAttribs, ShapePtr* pxShape ) +{ + switch( nElement ) + { + case XDR_TOKEN( sp ): + { + ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.CustomShape" ) ); + if( pxShape ) *pxShape = xShape; + return new ShapeContext( rParent, ShapePtr(), xShape ); + } + case XDR_TOKEN( cxnSp ): + { + ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.ConnectorShape" ) ); + if( pxShape ) *pxShape = xShape; + return new ConnectorShapeContext( rParent, ShapePtr(), xShape ); + } + case XDR_TOKEN( pic ): + { + ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.GraphicObjectShape" ) ); + if( pxShape ) *pxShape = xShape; + return new GraphicShapeContext( rParent, ShapePtr(), xShape ); + } + case XDR_TOKEN( graphicFrame ): + { + ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.GraphicObjectShape" ) ); + if( pxShape ) *pxShape = xShape; + return new GraphicalObjectFrameContext( rParent, ShapePtr(), xShape, rHelper.getSheetType() != SHEETTYPE_CHARTSHEET ); + } + case XDR_TOKEN( grpSp ): + { + ShapePtr xShape( new Shape( rHelper, rAttribs, "com.sun.star.drawing.GroupShape" ) ); + if( pxShape ) *pxShape = xShape; + return new OoxGroupShapeContext( rParent, rHelper, xShape ); + } + } + return 0; +} + +Reference< XFastContextHandler > SAL_CALL OoxGroupShapeContext::createFastChildContext( + sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException) +{ + ContextHandlerRef xContext = createShapeContext( *this, *this, nElement, AttributeList( rxAttribs ) ); + return xContext.get() ? xContext.get() : ShapeGroupContext::createFastChildContext( nElement, rxAttribs ); +} + +// ============================================================================ + OoxDrawingFragment::OoxDrawingFragment( const WorksheetHelper& rHelper, const OUString& rFragmentPath ) : OoxWorksheetFragmentBase( rHelper, rFragmentPath ), mxDrawPage( rHelper.getDrawPage(), UNO_QUERY ) @@ -438,31 +548,19 @@ ContextHandlerRef OoxDrawingFragment::onCreateContext( sal_Int32 nElement, const case XDR_TOKEN( absoluteAnchor ): case XDR_TOKEN( oneCellAnchor ): case XDR_TOKEN( twoCellAnchor ): + { switch( nElement ) { - case XDR_TOKEN( sp ): - mxShape.reset( new Shape( "com.sun.star.drawing.CustomShape" ) ); - return new ShapeContext( *this, ShapePtr(), mxShape ); - case XDR_TOKEN( cxnSp ): - mxShape.reset( new Shape( "com.sun.star.drawing.ConnectorShape" ) ); - return new ConnectorShapeContext( *this, ShapePtr(), mxShape ); - case XDR_TOKEN( pic ): - mxShape.reset( new Shape( "com.sun.star.drawing.GraphicObjectShape" ) ); - return new GraphicShapeContext( *this, ShapePtr(), mxShape ); - case XDR_TOKEN( graphicFrame ): - mxShape.reset( new Shape( "com.sun.star.drawing.OLE2Shape" ) ); - return new GraphicalObjectFrameContext( *this, ShapePtr(), mxShape, getSheetType() != SHEETTYPE_CHARTSHEET ); - case XDR_TOKEN( grpSp ): - mxShape.reset( new Shape( "com.sun.star.drawing.GroupShape" ) ); - return new ShapeGroupContext( *this, ShapePtr(), mxShape ); - case XDR_TOKEN( from ): case XDR_TOKEN( to ): return this; case XDR_TOKEN( pos ): if( mxAnchor.get() ) mxAnchor->importPos( rAttribs ); break; case XDR_TOKEN( ext ): if( mxAnchor.get() ) mxAnchor->importExt( rAttribs ); break; case XDR_TOKEN( clientData ): if( mxAnchor.get() ) mxAnchor->importClientData( rAttribs ); break; + + default: return OoxGroupShapeContext::createShapeContext( *this, *this, nElement, rAttribs, &mxShape ); } + } break; case XDR_TOKEN( from ): @@ -472,14 +570,14 @@ ContextHandlerRef OoxDrawingFragment::onCreateContext( sal_Int32 nElement, const case XDR_TOKEN( col ): case XDR_TOKEN( row ): case XDR_TOKEN( colOff ): - case XDR_TOKEN( rowOff ): return this; // collect index in onEndElement() + case XDR_TOKEN( rowOff ): return this; // collect index in onCharacters() } break; } return 0; } -void OoxDrawingFragment::onEndElement( const OUString& rChars ) +void OoxDrawingFragment::onCharacters( const OUString& rChars ) { switch( getCurrentElement() ) { @@ -487,8 +585,15 @@ void OoxDrawingFragment::onEndElement( const OUString& rChars ) case XDR_TOKEN( row ): case XDR_TOKEN( colOff ): case XDR_TOKEN( rowOff ): - if( mxAnchor.get() ) mxAnchor->setCellPos( getCurrentElement(), getPreviousElement(), rChars ); + if( mxAnchor.get() ) mxAnchor->setCellPos( getCurrentElement(), getParentElement(), rChars ); break; + } +} + +void OoxDrawingFragment::onEndElement() +{ + switch( getCurrentElement() ) + { case XDR_TOKEN( absoluteAnchor ): case XDR_TOKEN( oneCellAnchor ): case XDR_TOKEN( twoCellAnchor ): @@ -509,6 +614,8 @@ void OoxDrawingFragment::onEndElement( const OUString& rChars ) } // ============================================================================ +// VML +// ============================================================================ namespace { @@ -523,6 +630,8 @@ private: sal_Int32 mnRow; }; +// ---------------------------------------------------------------------------- + VmlFindNoteFunc::VmlFindNoteFunc( const CellAddress& rPos ) : mnCol( rPos.Column ), mnRow( rPos.Row ) @@ -531,19 +640,88 @@ VmlFindNoteFunc::VmlFindNoteFunc( const CellAddress& rPos ) : bool VmlFindNoteFunc::operator()( const ::oox::vml::ShapeBase& rShape ) const { - const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = rShape.getShapeModel().mxClientData; - return rxClientData.get() && (rxClientData->mnCol == mnCol) && (rxClientData->mnRow == mnRow); + const ::oox::vml::ClientData* pClientData = rShape.getClientData(); + return pClientData && (pClientData->mnCol == mnCol) && (pClientData->mnRow == mnRow); } } // namespace -// ---------------------------------------------------------------------------- +// ============================================================================ + +VmlControlMacroAttacher::VmlControlMacroAttacher( const OUString& rMacroName, + const Reference< XIndexContainer >& rxCtrlFormIC, sal_Int32 nCtrlIndex, sal_Int32 nCtrlType, sal_Int32 nDropStyle ) : + VbaMacroAttacherBase( rMacroName ), + mxCtrlFormIC( rxCtrlFormIC ), + mnCtrlIndex( nCtrlIndex ), + mnCtrlType( nCtrlType ), + mnDropStyle( nDropStyle ) +{ +} + +void VmlControlMacroAttacher::attachMacro( const OUString& rMacroUrl ) +{ + ScriptEventDescriptor aEventDesc; + aEventDesc.ScriptType = CREATE_OUSTRING( "Script" ); + aEventDesc.ScriptCode = rMacroUrl; + + // editable drop downs are treated like edit boxes + bool bEditDropDown = (mnCtrlType == XML_Drop) && (mnDropStyle == XML_ComboEdit); + sal_Int32 nCtrlType = bEditDropDown ? XML_Edit : mnCtrlType; + + switch( nCtrlType ) + { + case XML_Button: + case XML_Checkbox: + case XML_Radio: + aEventDesc.ListenerType = CREATE_OUSTRING( "XActionListener" ); + aEventDesc.EventMethod = CREATE_OUSTRING( "actionPerformed" ); + break; + case XML_Label: + case XML_GBox: + case XML_Dialog: + aEventDesc.ListenerType = CREATE_OUSTRING( "XMouseListener" ); + aEventDesc.EventMethod = CREATE_OUSTRING( "mouseReleased" ); + break; + case XML_Edit: + aEventDesc.ListenerType = CREATE_OUSTRING( "XTextListener" ); + aEventDesc.EventMethod = CREATE_OUSTRING( "textChanged" ); + break; + case XML_Spin: + case XML_Scroll: + aEventDesc.ListenerType = CREATE_OUSTRING( "XAdjustmentListener" ); + aEventDesc.EventMethod = CREATE_OUSTRING( "adjustmentValueChanged" ); + break; + case XML_List: + case XML_Drop: + aEventDesc.ListenerType = CREATE_OUSTRING( "XChangeListener" ); + aEventDesc.EventMethod = CREATE_OUSTRING( "changed" ); + break; + default: + OSL_ENSURE( false, "VmlControlMacroAttacher::attachMacro - unexpected object type" ); + return; + } + + try + { + Reference< XEventAttacherManager > xEventMgr( mxCtrlFormIC, UNO_QUERY_THROW ); + xEventMgr->registerScriptEvent( mnCtrlIndex, aEventDesc ); + } + catch( Exception& ) + { + } +} + +// ============================================================================ VmlDrawing::VmlDrawing( const WorksheetHelper& rHelper ) : ::oox::vml::Drawing( rHelper.getOoxFilter(), rHelper.getDrawPage(), ::oox::vml::VMLDRAWING_EXCEL ), WorksheetHelper( rHelper ), maControlConv( rHelper.getBaseFilter().getModel(), rHelper.getBaseFilter().getGraphicHelper() ) { + // default font for legacy listboxes and dropdowns: Tahoma, 8pt + maListBoxFont.moName = CREATE_OUSTRING( "Tahoma" ); + maListBoxFont.moColor = CREATE_OUSTRING( "auto" ); + maListBoxFont.monSize = 160; } const ::oox::vml::ShapeBase* VmlDrawing::getNoteShape( const CellAddress& rPos ) const @@ -553,11 +731,35 @@ const ::oox::vml::ShapeBase* VmlDrawing::getNoteShape( const CellAddress& rPos ) bool VmlDrawing::isShapeSupported( const ::oox::vml::ShapeBase& rShape ) const { - const ::oox::vml::ShapeModel::ShapeClientDataPtr& rxClientData = rShape.getShapeModel().mxClientData; - return !rxClientData.get() || (rxClientData->mnObjType != XML_Note); + const ::oox::vml::ClientData* pClientData = rShape.getClientData(); + return !pClientData || (pClientData->mnObjType != XML_Note); } -bool VmlDrawing::convertShapeClientAnchor( Rectangle& orShapeRect, const OUString& rShapeAnchor ) const +OUString VmlDrawing::getShapeBaseName( const ::oox::vml::ShapeBase& rShape ) const +{ + if( const ::oox::vml::ClientData* pClientData = rShape.getClientData() ) + { + switch( pClientData->mnObjType ) + { + case XML_Button: return CREATE_OUSTRING( "Button" ); + case XML_Checkbox: return CREATE_OUSTRING( "Check Box" ); + case XML_Dialog: return CREATE_OUSTRING( "Dialog Frame" ); + case XML_Drop: return CREATE_OUSTRING( "Drop Down" ); + case XML_Edit: return CREATE_OUSTRING( "Edit Box" ); + case XML_GBox: return CREATE_OUSTRING( "Group Box" ); + case XML_Label: return CREATE_OUSTRING( "Label" ); + case XML_List: return CREATE_OUSTRING( "List Box" ); + case XML_Note: return CREATE_OUSTRING( "Comment" ); + case XML_Pict: return (pClientData->mbDde || getOleObjectInfo( rShape.getShapeId() )) ? CREATE_OUSTRING( "Object" ) : CREATE_OUSTRING( "Picture" ); + case XML_Radio: return CREATE_OUSTRING( "Option Button" ); + case XML_Scroll: return CREATE_OUSTRING( "Scroll Bar" ); + case XML_Spin: return CREATE_OUSTRING( "Spinner" ); + } + } + return ::oox::vml::Drawing::getShapeBaseName( rShape ); +} + +bool VmlDrawing::convertClientAnchor( Rectangle& orShapeRect, const OUString& rShapeAnchor ) const { if( rShapeAnchor.getLength() == 0 ) return false; @@ -567,26 +769,310 @@ bool VmlDrawing::convertShapeClientAnchor( Rectangle& orShapeRect, const OUStrin return (orShapeRect.Width >= 0) && (orShapeRect.Height >= 0); } -void VmlDrawing::convertControlClientData( const Reference< XControlModel >& rxCtrlModel, - const ::oox::vml::ShapeClientData& rClientData ) const +Reference< XShape > VmlDrawing::createAndInsertClientXShape( const ::oox::vml::ShapeBase& rShape, + const Reference< XShapes >& rxShapes, const Rectangle& rShapeRect ) const { - if( rxCtrlModel.is() ) + // simulate the legacy drawing controls with OLE form controls + OUString aShapeName = rShape.getShapeName(); + const ::oox::vml::ClientData* pClientData = rShape.getClientData(); + if( (aShapeName.getLength() > 0) && pClientData ) { - PropertySet aPropSet( rxCtrlModel ); + Rectangle aShapeRect = rShapeRect; + const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper(); + const ::oox::vml::TextBox* pTextBox = rShape.getTextBox(); + EmbeddedControl aControl( aShapeName ); + switch( pClientData->mnObjType ) + { + case XML_Button: + { + AxCommandButtonModel& rAxModel = aControl.createModel< AxCommandButtonModel >(); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign ); + rAxModel.mnFlags = AX_FLAGS_ENABLED | AX_FLAGS_OPAQUE | AX_FLAGS_WORDWRAP; + rAxModel.mnVerticalAlign = pClientData->mnTextVAlign; + } + break; + + case XML_Label: + { + AxLabelModel& rAxModel = aControl.createModel< AxLabelModel >(); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign ); + rAxModel.mnFlags = AX_FLAGS_ENABLED | AX_FLAGS_WORDWRAP; + rAxModel.mnBorderStyle = AX_BORDERSTYLE_NONE; + rAxModel.mnSpecialEffect = AX_SPECIALEFFECT_FLAT; + rAxModel.mnVerticalAlign = pClientData->mnTextVAlign; + } + break; + + case XML_Edit: + { + bool bNumeric = (pClientData->mnVTEdit == ::oox::vml::VML_CLIENTDATA_INTEGER) || (pClientData->mnVTEdit == ::oox::vml::VML_CLIENTDATA_NUMBER); + AxMorphDataModelBase& rAxModel = bNumeric ? + static_cast< AxMorphDataModelBase& >( aControl.createModel< AxNumericFieldModel >() ) : + static_cast< AxMorphDataModelBase& >( aControl.createModel< AxTextBoxModel >() ); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maValue, pTextBox, pClientData->mnTextHAlign ); + setFlag( rAxModel.mnFlags, AX_FLAGS_MULTILINE, pClientData->mbMultiLine ); + setFlag( rAxModel.mnScrollBars, AX_SCROLLBAR_VERTICAL, pClientData->mbVScroll ); + if( pClientData->mbSecretEdit ) + rAxModel.mnPasswordChar = '*'; + } + break; + + case XML_GBox: + { + AxFrameModel& rAxModel = aControl.createModel< AxFrameModel >(); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign ); + rAxModel.mnBorderStyle = pClientData->mbNo3D ? AX_BORDERSTYLE_SINGLE : AX_BORDERSTYLE_NONE; + rAxModel.mnSpecialEffect = pClientData->mbNo3D ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_BUMPED; + + /* Move top border of groupbox up by half font height, because + Excel specifies Y position of the groupbox border line + instead the top border of the caption text. */ + if( const ::oox::vml::TextFontModel* pFontModel = pTextBox ? pTextBox->getFirstFont() : 0 ) + { + sal_Int32 nFontHeightHmm = getUnitConverter().scaleToMm100( pFontModel->monSize.get( 160 ), UNIT_TWIP ); + sal_Int32 nYDiff = ::std::min< sal_Int32 >( nFontHeightHmm / 2, aShapeRect.Y ); + aShapeRect.Y -= nYDiff; + aShapeRect.Height += nYDiff; + } + } + break; + + case XML_Checkbox: + { + AxCheckBoxModel& rAxModel = aControl.createModel< AxCheckBoxModel >(); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign ); + convertControlBackground( rAxModel, rShape ); + rAxModel.maValue = OUString::valueOf( pClientData->mnChecked ); + rAxModel.mnSpecialEffect = pClientData->mbNo3D ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN; + rAxModel.mnVerticalAlign = pClientData->mnTextVAlign; + bool bTriState = (pClientData->mnChecked != ::oox::vml::VML_CLIENTDATA_UNCHECKED) && (pClientData->mnChecked != ::oox::vml::VML_CLIENTDATA_CHECKED); + rAxModel.mnMultiSelect = bTriState ? AX_SELCTION_MULTI : AX_SELCTION_SINGLE; + } + break; + + case XML_Radio: + { + AxOptionButtonModel& rAxModel = aControl.createModel< AxOptionButtonModel >(); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, pClientData->mnTextHAlign ); + convertControlBackground( rAxModel, rShape ); + rAxModel.maValue = OUString::valueOf( pClientData->mnChecked ); + rAxModel.mnSpecialEffect = pClientData->mbNo3D ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN; + rAxModel.mnVerticalAlign = pClientData->mnTextVAlign; + } + break; - // printable - aPropSet.setProperty( PROP_Printable, rClientData.mbPrintObject ); + case XML_List: + { + AxListBoxModel& rAxModel = aControl.createModel< AxListBoxModel >(); + convertControlFontData( rAxModel.maFontData, rAxModel.mnTextColor, maListBoxFont ); + rAxModel.mnBorderStyle = pClientData->mbNo3D2 ? AX_BORDERSTYLE_SINGLE : AX_BORDERSTYLE_NONE; + rAxModel.mnSpecialEffect = pClientData->mbNo3D2 ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN; + switch( pClientData->mnSelType ) + { + case XML_Single: rAxModel.mnMultiSelect = AX_SELCTION_SINGLE; break; + case XML_Multi: rAxModel.mnMultiSelect = AX_SELCTION_MULTI; break; + case XML_Extend: rAxModel.mnMultiSelect = AX_SELCTION_EXTENDED; break; + } + } + break; - // control sources - if( (rClientData.maLinkedCell.getLength() > 0) || (rClientData.maSourceRange.getLength() > 0) ) - maControlConv.bindToSources( rxCtrlModel, rClientData.maLinkedCell, rClientData.maSourceRange, getSheetIndex() ); + case XML_Drop: + { + AxComboBoxModel& rAxModel = aControl.createModel< AxComboBoxModel >(); + convertControlFontData( rAxModel.maFontData, rAxModel.mnTextColor, maListBoxFont ); + rAxModel.mnDisplayStyle = AX_DISPLAYSTYLE_DROPDOWN; + rAxModel.mnShowDropButton = AX_SHOWDROPBUTTON_ALWAYS; + rAxModel.mnBorderStyle = pClientData->mbNo3D2 ? AX_BORDERSTYLE_SINGLE : AX_BORDERSTYLE_NONE; + rAxModel.mnSpecialEffect = pClientData->mbNo3D2 ? AX_SPECIALEFFECT_FLAT : AX_SPECIALEFFECT_SUNKEN; + rAxModel.mnListRows = pClientData->mnDropLines; + } + break; + + case XML_Spin: + { + AxSpinButtonModel& rAxModel = aControl.createModel< AxSpinButtonModel >(); + rAxModel.mnMin = pClientData->mnMin; + rAxModel.mnMax = pClientData->mnMax; + rAxModel.mnPosition = pClientData->mnVal; + rAxModel.mnSmallChange = pClientData->mnInc; + } + break; + + case XML_Scroll: + { + AxScrollBarModel& rAxModel = aControl.createModel< AxScrollBarModel >(); + rAxModel.mnMin = pClientData->mnMin; + rAxModel.mnMax = pClientData->mnMax; + rAxModel.mnPosition = pClientData->mnVal; + rAxModel.mnSmallChange = pClientData->mnInc; + rAxModel.mnLargeChange = pClientData->mnPage; + } + break; + + case XML_Dialog: + { + // fake with a group box + AxFrameModel& rAxModel = aControl.createModel< AxFrameModel >(); + convertControlText( rAxModel.maFontData, rAxModel.mnTextColor, rAxModel.maCaption, pTextBox, XML_Left ); + rAxModel.mnBorderStyle = AX_BORDERSTYLE_SINGLE; + rAxModel.mnSpecialEffect = AX_SPECIALEFFECT_FLAT; + } + break; + } + + if( ControlModelBase* pAxModel = aControl.getModel() ) + { + // create the control shape + pAxModel->maSize.first = aShapeRect.Width; + pAxModel->maSize.second = aShapeRect.Height; + sal_Int32 nCtrlIndex = -1; + Reference< XShape > xShape = createAndInsertXControlShape( aControl, rxShapes, aShapeRect, nCtrlIndex ); + + // control shape macro + if( xShape.is() && (nCtrlIndex >= 0) && (pClientData->maFmlaMacro.getLength() > 0) ) + { + OUString aMacroName = getFormulaParser().importMacroName( pClientData->maFmlaMacro ); + if( aMacroName.getLength() > 0 ) + { + Reference< XIndexContainer > xFormIC = getControlForm().getXForm(); + VbaMacroAttacherRef xAttacher( new VmlControlMacroAttacher( aMacroName, xFormIC, nCtrlIndex, pClientData->mnObjType, pClientData->mnDropStyle ) ); + getBaseFilter().getVbaProject().registerMacroAttacher( xAttacher ); + } + } + + return xShape; + } } + + return Reference< XShape >(); } -void VmlDrawing::notifyShapeInserted( const Reference< XShape >& /*rxShape*/, const Rectangle& rShapeRect ) +void VmlDrawing::notifyXShapeInserted( const Reference< XShape >& rxShape, + const Rectangle& rShapeRect, const ::oox::vml::ShapeBase& rShape, bool bGroupChild ) { - // collect all shape positions in the WorksheetHelper base class - extendShapeBoundingBox( rShapeRect ); + // collect all shape positions in the WorksheetHelper base class (but not children of group shapes) + if( !bGroupChild ) + extendShapeBoundingBox( rShapeRect ); + + // convert settings from VML client data + if( const ::oox::vml::ClientData* pClientData = rShape.getClientData() ) + { + // specific settings for embedded form controls + try + { + Reference< XControlShape > xCtrlShape( rxShape, UNO_QUERY_THROW ); + Reference< XControlModel > xCtrlModel( xCtrlShape->getControl(), UNO_SET_THROW ); + PropertySet aPropSet( xCtrlModel ); + + // printable + aPropSet.setProperty( PROP_Printable, pClientData->mbPrintObject ); + + // control source links + if( (pClientData->maFmlaLink.getLength() > 0) || (pClientData->maFmlaRange.getLength() > 0) ) + maControlConv.bindToSources( xCtrlModel, pClientData->maFmlaLink, pClientData->maFmlaRange, getSheetIndex() ); + } + catch( Exception& ) + { + } + } +} + +// private -------------------------------------------------------------------- + +sal_uInt32 VmlDrawing::convertControlTextColor( const OUString& rTextColor ) const +{ + // color attribute not present or 'auto' - use passed default color + if( (rTextColor.getLength() == 0) || rTextColor.equalsIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "auto" ) ) ) + return AX_SYSCOLOR_WINDOWTEXT; + + if( rTextColor[ 0 ] == '#' ) + { + // RGB colors in the format '#RRGGBB' + if( rTextColor.getLength() == 7 ) + return OleHelper::encodeOleColor( rTextColor.copy( 1 ).toInt32( 16 ) ); + + // RGB colors in the format '#RGB' + if( rTextColor.getLength() == 4 ) + { + sal_Int32 nR = rTextColor.copy( 1, 1 ).toInt32( 16 ) * 0x11; + sal_Int32 nG = rTextColor.copy( 2, 1 ).toInt32( 16 ) * 0x11; + sal_Int32 nB = rTextColor.copy( 3, 1 ).toInt32( 16 ) * 0x11; + return OleHelper::encodeOleColor( (nR << 16) | (nG << 8) | nB ); + } + + OSL_ENSURE( false, OStringBuffer( "VmlDrawing::convertControlTextColor - invalid color name '" ). + append( OUStringToOString( rTextColor, RTL_TEXTENCODING_ASCII_US ) ).append( '\'' ).getStr() ); + return AX_SYSCOLOR_WINDOWTEXT; + } + + const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper(); + + /* Predefined color names or system color names (resolve to RGB to detect + valid color name). */ + sal_Int32 nColorToken = AttributeConversion::decodeToken( rTextColor ); + sal_Int32 nRgbValue = Color::getVmlPresetColor( nColorToken, API_RGB_TRANSPARENT ); + if( nRgbValue == API_RGB_TRANSPARENT ) + nRgbValue = rGraphicHelper.getSystemColor( nColorToken, API_RGB_TRANSPARENT ); + if( nRgbValue != API_RGB_TRANSPARENT ) + return OleHelper::encodeOleColor( nRgbValue ); + + // try palette color + return OleHelper::encodeOleColor( rGraphicHelper.getPaletteColor( rTextColor.toInt32() ) ); +} + +void VmlDrawing::convertControlFontData( AxFontData& rAxFontData, sal_uInt32& rnOleTextColor, const ::oox::vml::TextFontModel& rFontModel ) const +{ + if( rFontModel.moName.has() ) + rAxFontData.maFontName = rFontModel.moName.get(); + + // font height: convert from twips to points, then to internal representation of AX controls + rAxFontData.setHeightPoints( static_cast< sal_Int16 >( (rFontModel.monSize.get( 200 ) + 10) / 20 ) ); + + // font effects + rAxFontData.mnFontEffects = 0; + setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_BOLD, rFontModel.mobBold.get( false ) ); + setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_ITALIC, rFontModel.mobItalic.get( false ) ); + setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_STRIKEOUT, rFontModel.mobStrikeout.get( false ) ); + sal_Int32 nUnderline = rFontModel.monUnderline.get( XML_none ); + setFlag( rAxFontData.mnFontEffects, AX_FONTDATA_UNDERLINE, nUnderline != XML_none ); + rAxFontData.mbDblUnderline = nUnderline == XML_double; + + // font color + rnOleTextColor = convertControlTextColor( rFontModel.moColor.get( OUString() ) ); +} + +void VmlDrawing::convertControlText( AxFontData& rAxFontData, sal_uInt32& rnOleTextColor, + OUString& rCaption, const ::oox::vml::TextBox* pTextBox, sal_Int32 nTextHAlign ) const +{ + if( pTextBox ) + { + rCaption = pTextBox->getText(); + if( const ::oox::vml::TextFontModel* pFontModel = pTextBox->getFirstFont() ) + convertControlFontData( rAxFontData, rnOleTextColor, *pFontModel ); + } + + switch( nTextHAlign ) + { + case XML_Left: rAxFontData.mnHorAlign = AX_FONTDATA_LEFT; break; + case XML_Center: rAxFontData.mnHorAlign = AX_FONTDATA_CENTER; break; + case XML_Right: rAxFontData.mnHorAlign = AX_FONTDATA_RIGHT; break; + default: rAxFontData.mnHorAlign = AX_FONTDATA_LEFT; + } +} + +void VmlDrawing::convertControlBackground( AxMorphDataModelBase& rAxModel, const ::oox::vml::ShapeBase& rShape ) const +{ + const ::oox::vml::FillModel& rFillModel = rShape.getTypeModel().maFillModel; + bool bHasFill = rFillModel.moFilled.get( true ); + setFlag( rAxModel.mnFlags, AX_FLAGS_OPAQUE, bHasFill ); + if( bHasFill ) + { + const GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper(); + sal_Int32 nSysWindowColor = rGraphicHelper.getSystemColor( XML_window, API_RGB_WHITE ); + ::oox::drawingml::Color aColor = ::oox::vml::ConversionHelper::decodeColor( rGraphicHelper, rFillModel.moColor, rFillModel.moOpacity, nSysWindowColor ); + sal_Int32 nRgbValue = aColor.getColor( rGraphicHelper ); + rAxModel.mnBackColor = OleHelper::encodeOleColor( nRgbValue ); + } } // ============================================================================ @@ -607,4 +1093,3 @@ void OoxVmlDrawingFragment::finalizeImport() } // namespace xls } // namespace oox - diff --git a/oox/source/xls/excelfilter.cxx b/oox/source/xls/excelfilter.cxx index 71475790851f..f07bfd48495f 100644 --- a/oox/source/xls/excelfilter.cxx +++ b/oox/source/xls/excelfilter.cxx @@ -26,36 +26,35 @@ ************************************************************************/ #include "oox/xls/excelfilter.hxx" + +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include "oox/dump/biffdumper.hxx" +#include "oox/dump/xlsbdumper.hxx" #include "oox/helper/binaryinputstream.hxx" #include "oox/xls/biffdetector.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/excelchartconverter.hxx" +#include "oox/xls/excelvbaproject.hxx" #include "oox/xls/stylesbuffer.hxx" #include "oox/xls/themebuffer.hxx" #include "oox/xls/workbookfragment.hxx" -#include "oox/dump/biffdumper.hxx" -#include "oox/dump/xlsbdumper.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::XInterface; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::xml::sax::XFastDocumentHandler; -using ::oox::core::BinaryFilterBase; -using ::oox::core::FragmentHandlerRef; -using ::oox::core::Relation; -using ::oox::core::Relations; -using ::oox::core::XmlFilterBase; -using ::oox::drawingml::table::TableStyleListPtr; namespace oox { namespace xls { // ============================================================================ +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using namespace ::oox::core; + +using ::rtl::OUString; +using ::oox::drawingml::table::TableStyleListPtr; + +// ============================================================================ + ExcelFilterBase::ExcelFilterBase() : mpData( 0 ) { @@ -160,6 +159,11 @@ GraphicHelper* ExcelFilter::implCreateGraphicHelper() const return new ExcelGraphicHelper( getWorkbookData() ); } +::oox::ole::VbaProject* ExcelFilter::implCreateVbaProject() const +{ + return new ExcelVbaProject( getGlobalFactory(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) ); +} + OUString ExcelFilter::implGetImplementationName() const { return ExcelFilter_getImplementationName(); @@ -235,6 +239,11 @@ GraphicHelper* ExcelBiffFilter::implCreateGraphicHelper() const return new ExcelGraphicHelper( getWorkbookData() ); } +::oox::ole::VbaProject* ExcelBiffFilter::implCreateVbaProject() const +{ + return new ExcelVbaProject( getGlobalFactory(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) ); +} + OUString ExcelBiffFilter::implGetImplementationName() const { return ExcelBiffFilter_getImplementationName(); @@ -244,4 +253,3 @@ OUString ExcelBiffFilter::implGetImplementationName() const } // namespace xls } // namespace oox - diff --git a/oox/source/xls/excelvbaproject.cxx b/oox/source/xls/excelvbaproject.cxx index 859dd8c733ba..3d7d34b87823 100755 --- a/oox/source/xls/excelvbaproject.cxx +++ b/oox/source/xls/excelvbaproject.cxx @@ -56,13 +56,13 @@ using ::rtl::OUStringBuffer; // ============================================================================ -VbaProject::VbaProject( const Reference< XMultiServiceFactory >& rxGlobalFactory, const Reference< XSpreadsheetDocument >& rxDocument ) : +ExcelVbaProject::ExcelVbaProject( const Reference< XMultiServiceFactory >& rxGlobalFactory, const Reference< XSpreadsheetDocument >& rxDocument ) : ::oox::ole::VbaProject( rxGlobalFactory, Reference< XModel >( rxDocument, UNO_QUERY ), CREATE_OUSTRING( "Calc" ) ), mxDocument( rxDocument ) { } -void VbaProject::attachToEvents() +void ExcelVbaProject::attachToEvents() { // do nothing is code is not executable if( !isImportVbaExecutable() ) @@ -125,7 +125,7 @@ void lclGenerateMissingCodeNames( CodeNameSet& rUsedCodeNames, SheetPropertySetL } // namespace -void VbaProject::prepareModuleImport() +void ExcelVbaProject::prepareImport() { /* Check if the sheets have imported codenames. Generate new unused codenames if not. */ @@ -169,9 +169,14 @@ void VbaProject::prepareModuleImport() } } +void ExcelVbaProject::finalizeImport() +{ + attachToEvents(); +} + // private -------------------------------------------------------------------- -void VbaProject::attachToDocumentEvents( const OUString& rCodeName ) +void ExcelVbaProject::attachToDocumentEvents( const OUString& rCodeName ) { if( (rCodeName.getLength() == 0) || !hasModule( rCodeName ) ) return; @@ -189,7 +194,7 @@ void VbaProject::attachToDocumentEvents( const OUString& rCodeName ) attachMacroToDocumentEvent( CREATE_OUSTRING( "OnPrepareUnload" ), rCodeName, CREATE_OUSTRING( "Workbook_BeforeClose" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO False" ) ); } -void VbaProject::attachToSheetEvents( const Reference< XEventsSupplier >& rxEventsSupp, const OUString& rCodeName ) +void ExcelVbaProject::attachToSheetEvents( const Reference< XEventsSupplier >& rxEventsSupp, const OUString& rCodeName ) { if( !rxEventsSupp.is() || (rCodeName.getLength() == 0) || !hasModule( rCodeName ) ) return; diff --git a/oox/source/xls/externallinkbuffer.cxx b/oox/source/xls/externallinkbuffer.cxx index 04fcd2f84648..648555474218 100644 --- a/oox/source/xls/externallinkbuffer.cxx +++ b/oox/source/xls/externallinkbuffer.cxx @@ -26,7 +26,7 @@ ************************************************************************/ #include "oox/xls/externallinkbuffer.hxx" -#include <rtl/strbuf.hxx> + #include <com/sun/star/sheet/ComplexReference.hpp> #include <com/sun/star/sheet/DDELinkInfo.hpp> #include <com/sun/star/sheet/ExternalLinkType.hpp> @@ -38,6 +38,7 @@ #include <com/sun/star/sheet/XDDELinkResults.hpp> #include <com/sun/star/sheet/XExternalDocLink.hpp> #include <com/sun/star/sheet/XExternalDocLinks.hpp> +#include <rtl/strbuf.hxx> #include "oox/helper/attributelist.hxx" #include "oox/core/filterbase.hxx" #include "oox/xls/addressconverter.hxx" @@ -46,31 +47,21 @@ #include "oox/xls/formulaparser.hxx" #include "oox/xls/worksheetbuffer.hxx" +namespace oox { +namespace xls { + +// ============================================================================ + +using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::table; +using namespace ::com::sun::star::uno; + +using ::oox::core::Relation; +using ::oox::core::Relations; using ::rtl::OString; using ::rtl::OStringBuffer; using ::rtl::OStringToOUString; 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::table::CellAddress; -using ::com::sun::star::sheet::ComplexReference; -using ::com::sun::star::sheet::DDEItemInfo; -using ::com::sun::star::sheet::DDELinkInfo; -using ::com::sun::star::sheet::ExternalLinkInfo; -using ::com::sun::star::sheet::ExternalReference; -using ::com::sun::star::sheet::SingleReference; -using ::com::sun::star::sheet::XDDELinks; -using ::com::sun::star::sheet::XDDELinkResults; -using ::com::sun::star::sheet::XExternalDocLinks; -using ::com::sun::star::sheet::XExternalSheetCache; -using ::oox::core::Relation; -using ::oox::core::Relations; - -namespace oox { -namespace xls { // ============================================================================ @@ -947,8 +938,10 @@ void RefSheetsModel::readBiff8Data( BiffInputStream& rStrm ) ExternalLinkBuffer::ExternalLinkBuffer( const WorkbookHelper& rHelper ) : WorkbookHelper( rHelper ), + mxSelfRef( new ExternalLink( rHelper ) ), mbUseRefSheets( false ) { + mxSelfRef->setSelfLinkType(); } ExternalLinkRef ExternalLinkBuffer::importExternalReference( const AttributeList& rAttribs ) @@ -1046,22 +1039,24 @@ void ExternalLinkBuffer::importExternSheet8( BiffInputStream& rStrm ) Sequence< ExternalLinkInfo > ExternalLinkBuffer::getLinkInfos() const { ::std::vector< ExternalLinkInfo > aLinkInfos; - // dummy entry for index 0 - aLinkInfos.push_back( ExternalLinkInfo( ::com::sun::star::sheet::ExternalLinkType::UNKNOWN, Any() ) ); + // should not be used for OOBIN documents + OSL_ENSURE( (getFilterType() == FILTER_OOX) && !mbUseRefSheets, "ExternalLinkBuffer::getLinkInfos - unexpected file format" ); + // add entry for implicit index 0 (self reference to this document) + aLinkInfos.push_back( mxSelfRef->getLinkInfo() ); for( ExternalLinkVec::const_iterator aIt = maExtLinks.begin(), aEnd = maExtLinks.end(); aIt != aEnd; ++aIt ) aLinkInfos.push_back( (*aIt)->getLinkInfo() ); return ContainerHelper::vectorToSequence( aLinkInfos ); } -ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId ) const +ExternalLinkRef ExternalLinkBuffer::getExternalLink( sal_Int32 nRefId, bool bUseRefSheets ) const { ExternalLinkRef xExtLink; switch( getFilterType() ) { case FILTER_OOX: - // OOXML: one-based index - if( !mbUseRefSheets ) - xExtLink = maLinks.get( nRefId - 1 ); + // OOXML: 0 = this document, otherwise one-based index into link list + if( !bUseRefSheets || !mbUseRefSheets ) + xExtLink = (nRefId == 0) ? mxSelfRef : maLinks.get( nRefId - 1 ); // OOBIN: zero-based index into ref-sheets list else if( const RefSheetsModel* pRefSheets = getRefSheets( nRefId ) ) xExtLink = maLinks.get( pRefSheets->mnExtRefId ); @@ -1140,4 +1135,3 @@ const RefSheetsModel* ExternalLinkBuffer::getRefSheets( sal_Int32 nRefId ) const } // namespace xls } // namespace oox - diff --git a/oox/source/xls/externallinkfragment.cxx b/oox/source/xls/externallinkfragment.cxx index 15aaf8bc5412..16bd11bc5144 100644 --- a/oox/source/xls/externallinkfragment.cxx +++ b/oox/source/xls/externallinkfragment.cxx @@ -69,32 +69,30 @@ ContextHandlerRef OoxExternalSheetDataContext::onCreateContext( sal_Int32 nEleme if( nElement == XLS_TOKEN( cell ) ) { importCell( rAttribs ); return this; } break; case XLS_TOKEN( cell ): - if( nElement == XLS_TOKEN( v ) ) return this; // collect characters in onEndElement() + if( nElement == XLS_TOKEN( v ) ) return this; // collect characters in onCharacters() break; } return 0; } -void OoxExternalSheetDataContext::onEndElement( const OUString& rChars ) +void OoxExternalSheetDataContext::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) + if( isCurrentElement( XLS_TOKEN( v ) ) ) { - case XLS_TOKEN( v ): - switch( mnCurrType ) - { - case XML_b: - case XML_n: - setCellValue( Any( rChars.toDouble() ) ); - break; - case XML_e: - setCellValue( Any( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( rChars ) ) ) ); - break; - case XML_str: - setCellValue( Any( rChars ) ); - break; - } - mnCurrType = XML_TOKEN_INVALID; - break; + switch( mnCurrType ) + { + case XML_b: + case XML_n: + setCellValue( Any( rChars.toDouble() ) ); + break; + case XML_e: + setCellValue( Any( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( rChars ) ) ) ); + break; + case XML_str: + setCellValue( Any( rChars ) ); + break; + } + mnCurrType = XML_TOKEN_INVALID; } } @@ -245,7 +243,7 @@ ContextHandlerRef OoxExternalLinkFragment::onCreateContext( sal_Int32 nElement, } break; case XLS_TOKEN( value ): - if( nElement == XLS_TOKEN( val ) ) return this; // collect value in onEndElement() + if( nElement == XLS_TOKEN( val ) ) return this; // collect value in onCharacters() break; case XLS_TOKEN( oleLink ): @@ -258,32 +256,30 @@ ContextHandlerRef OoxExternalLinkFragment::onCreateContext( sal_Int32 nElement, return false; } -void OoxExternalLinkFragment::onEndElement( const OUString& rChars ) +void OoxExternalLinkFragment::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) + if( isCurrentElement( XLS_TOKEN( val ) ) ) + maResultValue = rChars; +} + +void OoxExternalLinkFragment::onEndElement() +{ + if( isCurrentElement( XLS_TOKEN( value ) ) && mxExtName.get() ) switch( mnResultType ) { - case XLS_TOKEN( val ): - maResultValue = rChars; + case XML_b: + mxExtName->appendResultValue( maResultValue.toDouble() ); break; - case XLS_TOKEN( value ): - if( mxExtName.get() ) switch( mnResultType ) - { - case XML_b: - mxExtName->appendResultValue( maResultValue.toDouble() ); - break; - case XML_e: - mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( maResultValue ) ) ); - break; - case XML_n: - mxExtName->appendResultValue( maResultValue.toDouble() ); - break; - case XML_str: - mxExtName->appendResultValue( maResultValue ); - break; - default: - mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ); - } + case XML_e: + mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( getUnitConverter().calcBiffErrorCode( maResultValue ) ) ); + break; + case XML_n: + mxExtName->appendResultValue( maResultValue.toDouble() ); + break; + case XML_str: + mxExtName->appendResultValue( maResultValue ); break; + default: + mxExtName->appendResultValue( BiffHelper::calcDoubleFromError( BIFF_ERR_NA ) ); } } diff --git a/oox/source/xls/formulaparser.cxx b/oox/source/xls/formulaparser.cxx index 12deadecd695..e3a8282e1a15 100644 --- a/oox/source/xls/formulaparser.cxx +++ b/oox/source/xls/formulaparser.cxx @@ -439,7 +439,7 @@ public: const ApiTokenSequence& rTokens ); /** Tries to resolve the passed ref-id to an OLE target URL. */ - OUString resolveOleTarget( sal_Int32 nRefId ) const; + OUString resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const; protected: typedef ::std::pair< sal_Int32, bool > WhiteSpace; @@ -605,9 +605,9 @@ void FormulaParserImpl::setFormula( FormulaContext& rContext, const ApiTokenSequ finalizeImport( rTokens ); } -OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId ) const +OUString FormulaParserImpl::resolveOleTarget( sal_Int32 nRefId, bool bUseRefSheets ) const { - const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId ).get(); + const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, bUseRefSheets ).get(); OSL_ENSURE( pExtLink && (pExtLink->getLinkType() == LINKTYPE_OLE), "FormulaParserImpl::resolveOleTarget - missing or wrong link" ); if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_OLE) ) return getBaseFilter().getAbsoluteUrl( pExtLink->getTargetUrl() ); @@ -2734,6 +2734,29 @@ bool BiffFormulaParserImpl::pushBiffFunction( sal_uInt16 nFuncId, sal_uInt8 nPar // ============================================================================ +namespace { + +/** Extracts the reference identifier and the remaining data from a formula in + the format '[RefID]Remaining'. */ +bool lclExtractRefId( sal_Int32& rnRefId, OUString& rRemainder, const OUString& rFormulaString ) +{ + if( (rFormulaString.getLength() >= 4) && (rFormulaString[ 0 ] == '[') ) + { + sal_Int32 nBracketClose = rFormulaString.indexOf( ']', 1 ); + if( nBracketClose >= 2 ) + { + rnRefId = rFormulaString.copy( 1, nBracketClose - 1 ).toInt32(); + rRemainder = rFormulaString.copy( nBracketClose + 1 ); + return rRemainder.getLength() > 0; + } + } + return false; +} + +} + +// ---------------------------------------------------------------------------- + FormulaParser::FormulaParser( const WorkbookHelper& rHelper ) : FormulaProcessorBase( rHelper ) { @@ -2808,24 +2831,12 @@ void FormulaParser::convertNumberToHyperlink( FormulaContext& rContext, const OU OUString FormulaParser::importOleTargetLink( const OUString& rFormulaString ) { - // obviously, this would overburden our formula parser, so we parse it manually - OUString aTargetLink; - sal_Int32 nFmlaLen = rFormulaString.getLength(); - if( (nFmlaLen >= 8) && (rFormulaString[ 0 ] == '[') ) - { - // passed string is trimmed already - sal_Int32 nBracketClose = rFormulaString.indexOf( ']' ); - sal_Int32 nExclamation = rFormulaString.indexOf( '!' ); - if( (nBracketClose >= 2) && - (nBracketClose + 1 == nExclamation) && - (rFormulaString[ nExclamation + 1 ] == '\'') && - (rFormulaString[ nFmlaLen - 1 ] == '\'') ) - { - sal_Int32 nRefId = rFormulaString.copy( 1, nBracketClose - 1 ).toInt32(); - aTargetLink = mxImpl->resolveOleTarget( nRefId ); - } - } - return aTargetLink; + sal_Int32 nRefId = -1; + OUString aRemainder; + if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() >= 3) && + (aRemainder[ 0 ] == '!') && (aRemainder[ 1 ] == '\'') && (aRemainder[ aRemainder.getLength() - 1 ] == '\'') ) + return mxImpl->resolveOleTarget( nRefId, false ); + return OUString(); } OUString FormulaParser::importOleTargetLink( RecordInputStream& rStrm ) @@ -2840,7 +2851,7 @@ OUString FormulaParser::importOleTargetLink( RecordInputStream& rStrm ) sal_Int32 nNameId; rStrm >> nToken >> nRefId >> nNameId; if( nToken == (BIFF_TOKCLASS_VAL|BIFF_TOKID_NAMEX) ) - aTargetLink = mxImpl->resolveOleTarget( nRefId ); + aTargetLink = mxImpl->resolveOleTarget( nRefId, true ); } rStrm.seek( nFmlaEndPos ); return aTargetLink; @@ -2854,8 +2865,60 @@ OUString FormulaParser::importOleTargetLink( BiffInputStream& rStrm, const sal_u return aTargetLink; } +OUString FormulaParser::importMacroName( const OUString& rFormulaString ) +{ + /* Valid macros are either sheet macros or VBA macros. OOXML and all BIFF + documents store defined names for sheet macros, but OOXML documents do + not store any defined name for VBA macros (while BIFF documents do). + Sheet macros may be defined locally to a sheet, or globally to the + document. As a result, all of the following macro specifiers are valid: + + 1) Macros located in the own document: + [0]!MySheetMacro (global sheet macro 'MySheetMacro') + Macro1!MyMacro (sheet-local sheet macro 'MyMacro') + [0]!MyVBAProc (VBA macro 'MyVBAProc') + [0]!Mod1.MyVBAProc (VBA macro 'MyVBAProc' from code module 'Mod1') + + 2) Macros from an external document: + [2]!MySheetMacro (global external sheet macro 'MySheetMacro') + [2]Macro1!MyMacro (sheet-local external sheet macro 'MyMacro') + [2]!MyVBAProc (external VBA macro 'MyVBAProc') + [2]!Mod1.MyVBAProc (external VBA macro from code module 'Mod1') + + This implementation is only interested in VBA macros from the own + document, ignoring the valid syntax 'Macro1!MyMacro' for sheet-local + sheet macros. + */ + sal_Int32 nRefId = -1; + OUString aRemainder; + if( lclExtractRefId( nRefId, aRemainder, rFormulaString ) && (aRemainder.getLength() > 1) && (aRemainder[ 0 ] == '!') ) + { + /* In BIFF12 documents, the reference identifier is always the + one-based index of the external link as it is in OOXML documents + (it is not an index into the list of reference sheets as used in + cell formulas). Index 0 is an implicit placeholder for the own + document. In BIFF12 documents, the reference to the own document is + stored explicitly, mostly at the top of the list, so index 1 may + resolve to the own document too. + Passing 'false' to getExternalLink() specifies to ignore the + reference sheets list (if existing) and to access the list of + external links directly. */ + const ExternalLink* pExtLink = getExternalLinks().getExternalLink( nRefId, false ).get(); + OSL_ENSURE( pExtLink, "FormulaParser::importMacroName - missing link" ); + // do not accept macros in external documents (not supported) + if( pExtLink && (pExtLink->getLinkType() == LINKTYPE_SELF) ) + { + // ignore sheet macros (defined name for VBA macros may not exist, see above) + OUString aMacroName = aRemainder.copy( 1 ); + const DefinedName* pDefName = getDefinedNames().getByModelName( aMacroName ).get(); + if( !pDefName || pDefName->isVBName() ) + return aMacroName; + } + } + return OUString(); +} + // ============================================================================ } // namespace xls } // namespace oox - diff --git a/oox/source/xls/richstringcontext.cxx b/oox/source/xls/richstringcontext.cxx index 4eb3f5e91a4f..ba022041f651 100644 --- a/oox/source/xls/richstringcontext.cxx +++ b/oox/source/xls/richstringcontext.cxx @@ -44,10 +44,18 @@ ContextHandlerRef OoxRichStringContext::onCreateContext( sal_Int32 nElement, con { switch( nElement ) { - case XLS_TOKEN( t ): mxPortion = mxString->importText( rAttribs ); return this; // collect text in onEndElement() - case XLS_TOKEN( r ): mxPortion = mxString->importRun( rAttribs ); return this; - case XLS_TOKEN( rPh ): mxPhonetic = mxString->importPhoneticRun( rAttribs ); return this; - case XLS_TOKEN( phoneticPr ): mxString->importPhoneticPr( rAttribs ); break; + case XLS_TOKEN( t ): + mxPortion = mxString->importText( rAttribs ); + return this; // collect text in onCharacters() + case XLS_TOKEN( r ): + mxPortion = mxString->importRun( rAttribs ); + return this; + case XLS_TOKEN( rPh ): + mxPhonetic = mxString->importPhoneticRun( rAttribs ); + return this; + case XLS_TOKEN( phoneticPr ): + mxString->importPhoneticPr( rAttribs ); + break; } } else switch( getCurrentElement() ) @@ -61,7 +69,7 @@ ContextHandlerRef OoxRichStringContext::onCreateContext( sal_Int32 nElement, con break; case XLS_TOKEN( t ): - return this; // collect portion text in onEndElement() + return this; // collect portion text in onCharacters() } break; @@ -69,22 +77,24 @@ ContextHandlerRef OoxRichStringContext::onCreateContext( sal_Int32 nElement, con switch( nElement ) { case XLS_TOKEN( t ): - return this; // collect phonetic text in onEndElement() + return this; // collect phonetic text in onCharacters() } break; } return 0; } -void OoxRichStringContext::onEndElement( const OUString& rChars ) +void OoxRichStringContext::onCharacters( const OUString& rChars ) { - if( getCurrentElement() == XLS_TOKEN( t ) ) + if( isCurrentElement( XLS_TOKEN( t ) ) ) switch( getParentElement() ) { - switch( getPreviousElement() ) - { - case XLS_TOKEN( rPh ): if( mxPhonetic.get() ) mxPhonetic->setText( rChars ); break; - default: if( mxPortion.get() ) mxPortion->setText( rChars ); break; - } + case XLS_TOKEN( rPh ): + if( mxPhonetic.get() ) + mxPhonetic->setText( rChars ); + break; + default: + if( mxPortion.get() ) + mxPortion->setText( rChars ); } } diff --git a/oox/source/xls/sheetdatacontext.cxx b/oox/source/xls/sheetdatacontext.cxx index 05e4c5bfe767..667d093d2cb6 100644 --- a/oox/source/xls/sheetdatacontext.cxx +++ b/oox/source/xls/sheetdatacontext.cxx @@ -198,7 +198,7 @@ ContextHandlerRef OoxSheetDataContext::onCreateContext( sal_Int32 nElement, cons return 0; } -void OoxSheetDataContext::onEndElement( const OUString& rChars ) +void OoxSheetDataContext::onCharacters( const OUString& rChars ) { switch( getCurrentElement() ) { @@ -252,44 +252,45 @@ void OoxSheetDataContext::onEndElement( const OUString& rChars ) break; default: - OSL_ENSURE( false, "OoxSheetDataContext::onEndElement - unknown formula type" ); + OSL_ENSURE( false, "OoxSheetDataContext::onCharacters - unknown formula type" ); } } catch( Exception& ) { } break; + } +} - case XLS_TOKEN( c ): - if( maCurrCell.mxCell.is() ) +void OoxSheetDataContext::onEndElement() +{ + if( isCurrentElement( XLS_TOKEN( c ) ) && maCurrCell.mxCell.is() ) + { + if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) + { + if( maCurrCell.mbHasValueStr ) { - if( maCurrCell.mxCell->getType() == CellContentType_EMPTY ) - { - if( maCurrCell.mbHasValueStr ) - { - // implemented in WorksheetHelper class - setCell( maCurrCell ); - } - else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() ) - { - // convert font settings - mxInlineStr->finalizeImport(); - // write string to cell - Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); - if( xText.is() ) - mxInlineStr->convert( xText, maCurrCell.mnXfId ); - } - else - { - // empty cell, update cell type - maCurrCell.mnCellType = XML_TOKEN_INVALID; - } - } - - // store the cell formatting data - setCellFormat( maCurrCell ); + // implemented in WorksheetHelper class + setCell( maCurrCell ); } - break; + else if( (maCurrCell.mnCellType == XML_inlineStr) && mxInlineStr.get() ) + { + // convert font settings + mxInlineStr->finalizeImport(); + // write string to cell + Reference< XText > xText( maCurrCell.mxCell, UNO_QUERY ); + if( xText.is() ) + mxInlineStr->convert( xText, maCurrCell.mnXfId ); + } + else + { + // empty cell, update cell type + maCurrCell.mnCellType = XML_TOKEN_INVALID; + } + } + + // store the cell formatting data + setCellFormat( maCurrCell ); } } diff --git a/oox/source/xls/workbookfragment.cxx b/oox/source/xls/workbookfragment.cxx index 6e43a32495be..6322bd94c480 100644 --- a/oox/source/xls/workbookfragment.cxx +++ b/oox/source/xls/workbookfragment.cxx @@ -128,14 +128,10 @@ ContextHandlerRef OoxWorkbookFragment::onCreateContext( sal_Int32 nElement, cons return 0; } -void OoxWorkbookFragment::onEndElement( const OUString& rChars ) +void OoxWorkbookFragment::onCharacters( const OUString& rChars ) { - switch( getCurrentElement() ) - { - case XLS_TOKEN( definedName ): - if( mxCurrName.get() ) mxCurrName->setFormula( rChars ); - break; - } + if( isCurrentElement( XLS_TOKEN( definedName ) ) && mxCurrName.get() ) + mxCurrName->setFormula( rChars ); } ContextHandlerRef OoxWorkbookFragment::onCreateRecordContext( sal_Int32 nRecId, RecordInputStream& rStrm ) diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx index afeed95accca..5b7e9699d76b 100644 --- a/oox/source/xls/workbookhelper.cxx +++ b/oox/source/xls/workbookhelper.cxx @@ -26,31 +26,31 @@ ************************************************************************/ #include "oox/xls/workbookhelper.hxx" -#include <osl/thread.h> + +#include <com/sun/star/awt/XDevice.hpp> #include <com/sun/star/container/XIndexAccess.hpp> #include <com/sun/star/container/XNameContainer.hpp> -#include <com/sun/star/awt/XDevice.hpp> #include <com/sun/star/document/XActionLockable.hpp> -#include <com/sun/star/table/CellAddress.hpp> -#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> -#include <com/sun/star/sheet/XSpreadsheet.hpp> -#include <com/sun/star/sheet/XNamedRange.hpp> -#include <com/sun/star/sheet/XNamedRanges.hpp> #include <com/sun/star/sheet/XDatabaseRanges.hpp> #include <com/sun/star/sheet/XExternalDocLinks.hpp> +#include <com/sun/star/sheet/XNamedRange.hpp> +#include <com/sun/star/sheet/XNamedRanges.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/style/XStyle.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> -#include "properties.hxx" +#include <com/sun/star/table/CellAddress.hpp> +#include <osl/thread.h> +#include "oox/drawingml/theme.hxx" #include "oox/helper/progressbar.hxx" #include "oox/helper/propertyset.hxx" -#include "oox/drawingml/theme.hxx" +#include "oox/ole/vbaproject.hxx" #include "oox/xls/addressconverter.hxx" #include "oox/xls/biffinputstream.hxx" #include "oox/xls/biffcodec.hxx" #include "oox/xls/defnamesbuffer.hxx" #include "oox/xls/excelchartconverter.hxx" #include "oox/xls/excelfilter.hxx" -#include "oox/xls/excelvbaproject.hxx" #include "oox/xls/externallinkbuffer.hxx" #include "oox/xls/formulaparser.hxx" #include "oox/xls/pagesettings.hxx" @@ -66,40 +66,28 @@ #include "oox/xls/webquerybuffer.hxx" #include "oox/xls/workbooksettings.hxx" #include "oox/xls/worksheetbuffer.hxx" +#include "properties.hxx" + +namespace oox { +namespace xls { + +// ============================================================================ + +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::sheet; +using namespace ::com::sun::star::style; +using namespace ::com::sun::star::table; +using namespace ::com::sun::star::uno; -using ::rtl::OUString; -using ::com::sun::star::uno::Any; -using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::Exception; -using ::com::sun::star::uno::UNO_QUERY; -using ::com::sun::star::uno::UNO_QUERY_THROW; -using ::com::sun::star::uno::UNO_SET_THROW; -using ::com::sun::star::container::XIndexAccess; -using ::com::sun::star::container::XNameAccess; -using ::com::sun::star::container::XNameContainer; -using ::com::sun::star::lang::XMultiServiceFactory; -using ::com::sun::star::awt::XDevice; -using ::com::sun::star::document::XActionLockable; -using ::com::sun::star::table::CellAddress; -using ::com::sun::star::table::CellRangeAddress; -using ::com::sun::star::table::XCell; -using ::com::sun::star::table::XCellRange; -using ::com::sun::star::sheet::XSpreadsheetDocument; -using ::com::sun::star::sheet::XSpreadsheet; -using ::com::sun::star::sheet::XNamedRange; -using ::com::sun::star::sheet::XNamedRanges; -using ::com::sun::star::sheet::XDatabaseRanges; -using ::com::sun::star::sheet::XExternalDocLinks; -using ::com::sun::star::style::XStyle; -using ::com::sun::star::style::XStyleFamiliesSupplier; using ::oox::core::BinaryFilterBase; using ::oox::core::FilterBase; using ::oox::core::FragmentHandler; using ::oox::core::XmlFilterBase; using ::oox::drawingml::Theme; - -namespace oox { -namespace xls { +using ::rtl::OUString; // ============================================================================ @@ -613,6 +601,8 @@ void WorkbookData::finalize() aPropSet.setProperty( PROP_IsUndoEnabled, true ); // disable editing read-only documents (e.g. from read-only files) aPropSet.setProperty( PROP_IsChangeReadOnlyEnabled, false ); + // #111099# open forms in alive mode (has no effect, if no controls in document) + aPropSet.setProperty( PROP_ApplyFormDesignMode, false ); } } @@ -691,11 +681,7 @@ void WorkbookHelper::finalizeWorkbookImport() sheet events. */ StorageRef xVbaPrjStrg = mrBookData.getVbaProjectStorage(); if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() ) - { - VbaProject aVbaProject( getGlobalFactory(), getDocument() ); - aVbaProject.importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() ); - aVbaProject.attachToEvents(); - } + getBaseFilter().getVbaProject().importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() ); } // document model ------------------------------------------------------------- @@ -1004,4 +990,3 @@ bool WorkbookHelperRoot::isValid() const } // namespace xls } // namespace oox - diff --git a/oox/source/xls/worksheetfragment.cxx b/oox/source/xls/worksheetfragment.cxx index d75c92832994..7b397792d117 100644 --- a/oox/source/xls/worksheetfragment.cxx +++ b/oox/source/xls/worksheetfragment.cxx @@ -119,7 +119,7 @@ ContextHandlerRef OoxDataValidationsContext::onCreateContext( sal_Int32 nElement { case XLS_TOKEN( formula1 ): case XLS_TOKEN( formula2 ): - return this; // collect formulas in onEndElement() + return this; // collect formulas in onCharacters() } break; } @@ -138,7 +138,7 @@ ApiTokenSequence lclImportDataValFormula( FormulaParser& rParser, const OUString } // namespace -void OoxDataValidationsContext::onEndElement( const OUString& rChars ) +void OoxDataValidationsContext::onCharacters( const OUString& rChars ) { if( mxValModel.get() ) switch( getCurrentElement() ) { @@ -153,10 +153,15 @@ void OoxDataValidationsContext::onEndElement( const OUString& rChars ) mxValModel->maTokens2 = lclImportDataValFormula( getFormulaParser(), rChars, mxValModel->maRanges.getBaseAddress() ); break; - case XLS_TOKEN( dataValidation ): - setValidation( *mxValModel ); - mxValModel.reset(); - break; + } +} + +void OoxDataValidationsContext::onEndElement() +{ + if( isCurrentElement( XLS_TOKEN( dataValidation ) ) && mxValModel.get() ) + { + setValidation( *mxValModel ); + mxValModel.reset(); } } @@ -252,7 +257,7 @@ ContextHandlerRef OoxWorksheetFragment::onCreateContext( sal_Int32 nElement, con case SHEETTYPE_WORKSHEET: return (nElement == XLS_TOKEN( worksheet )) ? this : 0; case SHEETTYPE_CHARTSHEET: return 0; case SHEETTYPE_MACROSHEET: return (nElement == XM_TOKEN( macrosheet )) ? this : 0; - case SHEETTYPE_DIALOGSHEET: return (nElement == XM_TOKEN( dialogsheet )) ? this : 0; + case SHEETTYPE_DIALOGSHEET: return (nElement == XLS_TOKEN( dialogsheet )) ? this : 0; case SHEETTYPE_MODULESHEET: return 0; case SHEETTYPE_EMPTYSHEET: return 0; } @@ -260,6 +265,7 @@ ContextHandlerRef OoxWorksheetFragment::onCreateContext( sal_Int32 nElement, con case XLS_TOKEN( worksheet ): case XM_TOKEN( macrosheet ): + case XLS_TOKEN( dialogsheet ): switch( nElement ) { case XLS_TOKEN( sheetData ): return new OoxSheetDataContext( *this ); @@ -340,7 +346,7 @@ ContextHandlerRef OoxWorksheetFragment::onCreateContext( sal_Int32 nElement, con case XLS_TOKEN( oddHeader ): case XLS_TOKEN( oddFooter ): case XLS_TOKEN( evenHeader ): - case XLS_TOKEN( evenFooter ): return this; // collect h/f contents in onEndElement() + case XLS_TOKEN( evenFooter ): return this; // collect h/f contents in onCharacters() } break; @@ -354,7 +360,7 @@ ContextHandlerRef OoxWorksheetFragment::onCreateContext( sal_Int32 nElement, con return 0; } -void OoxWorksheetFragment::onEndElement( const OUString& rChars ) +void OoxWorksheetFragment::onCharacters( const OUString& rChars ) { switch( getCurrentElement() ) { |