summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans-Joachim Lankenau <hjs@openoffice.org>2010-12-17 13:36:59 +0100
committerHans-Joachim Lankenau <hjs@openoffice.org>2010-12-17 13:36:59 +0100
commite287dbe026bc3605ef8b9f89ff6e479ea219f49c (patch)
tree912c7c66388cf7c759c6cf59cba00831ca342656
parentCWS-TOOLING: integrate CWS gnumake2 (diff)
parentmib19: rebase to DEV300m95 (diff)
downloadcore-e287dbe026bc3605ef8b9f89ff6e479ea219f49c.tar.gz
core-e287dbe026bc3605ef8b9f89ff6e479ea219f49c.zip
CWS-TOOLING: integrate CWS mib19
-rw-r--r--filter/source/msfilter/msvbahelper.cxx27
-rw-r--r--filter/source/msfilter/svxmsbas.cxx10
-rw-r--r--[-rwxr-xr-x]oox/inc/oox/ole/vbamodule.hxx19
-rw-r--r--oox/inc/oox/ole/vbaproject.hxx21
-rwxr-xr-xoox/inc/oox/xls/excelvbaproject.hxx68
-rw-r--r--oox/prj/d.lst1
-rw-r--r--oox/source/ole/vbamodule.cxx79
-rw-r--r--oox/source/ole/vbaproject.cxx107
-rwxr-xr-xoox/source/xls/excelvbaproject.cxx161
-rw-r--r--oox/source/xls/makefile.mk1
-rw-r--r--oox/source/xls/workbookhelper.cxx4
11 files changed, 442 insertions, 56 deletions
diff --git a/filter/source/msfilter/msvbahelper.cxx b/filter/source/msfilter/msvbahelper.cxx
index 19e93dbb791a..e40c3c2c61c2 100644
--- a/filter/source/msfilter/msvbahelper.cxx
+++ b/filter/source/msfilter/msvbahelper.cxx
@@ -92,6 +92,24 @@ SfxObjectShell* findShellForUrl( const rtl::OUString& sMacroURLOrPath )
, rtl::OUStringToOString( xModel->getURL(), RTL_TEXTENCODING_UTF8 ).getStr()
, rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr()
);
+ ::rtl::OUString aName = xModel->getURL() ;
+ if (0 == aName.getLength())
+ {
+
+ const static rtl::OUString sTitle( RTL_CONSTASCII_USTRINGPARAM("Title" ) );
+ uno::Reference< frame::XFrame > xFrame( xModel->getCurrentController()->getFrame(), uno::UNO_QUERY_THROW );
+ uno::Reference< beans::XPropertySet > xProps( xFrame, uno::UNO_QUERY_THROW );
+ xProps->getPropertyValue(sTitle) >>= aName;
+ sal_Int32 pos = 0;
+ aName = aName.getToken(0,'-',pos);
+ aName = aName.trim();
+ if( sMacroURLOrPath.lastIndexOf( aName ) >= 0 )
+ {
+ pFoundShell = pShell;
+ break;
+ }
+ }
+
if ( sMacroURLOrPath.endsWithIgnoreAsciiCaseAsciiL( ".dot", 4 ) )
{
uno::Reference< document::XDocumentInfoSupplier > xDocInfoSupp( xModel, uno::UNO_QUERY );
@@ -261,10 +279,13 @@ VBAMacroResolvedInfo resolveVBAMacro( SfxObjectShell* pShell, const rtl::OUStrin
// 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 );
+
+ // As long as service VBAProjectNameProvider isn't supported in the model, disable the createInstance call
+ // (the ServiceNotRegisteredException is wrongly caught in ScModelObj::createInstance)
+ //uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY);
+ //if ( xSF.is() )
+ // xPrjNameCache.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAProjectNameProvider" ) ) ), uno::UNO_QUERY );
std::vector< rtl::OUString > sSearchList;
diff --git a/filter/source/msfilter/svxmsbas.cxx b/filter/source/msfilter/svxmsbas.cxx
index 5214b2d022c3..d17af3b2681b 100644
--- a/filter/source/msfilter/svxmsbas.cxx
+++ b/filter/source/msfilter/svxmsbas.cxx
@@ -252,14 +252,12 @@ BOOL SvxImportMSVBasic::ImportCode_Impl( const String& rStorageName,
Reference<XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer();
DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
+ /* Set library container to VBA compatibility mode. This will create
+ the VBA Globals object and store it in the Basic manager of the
+ document. */
if( !bAsComment ) try
{
- Reference< vba::XVBACompatibility > xVBACompat( xLibContainer, UNO_QUERY_THROW );
- xVBACompat->setVBACompatibilityMode( sal_True );
- /* Force creation of the VBAGlobals object, each application will
- create the right one and store it at the Basic manager. */
- Reference< XMultiServiceFactory > xFactory( rDocSh.GetModel(), UNO_QUERY_THROW );
- xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) );
+ Reference< vba::XVBACompatibility >( xLibContainer, UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True );
}
catch( Exception& )
{
diff --git a/oox/inc/oox/ole/vbamodule.hxx b/oox/inc/oox/ole/vbamodule.hxx
index 3b529ceee129..377c7abc335a 100755..100644
--- a/oox/inc/oox/ole/vbamodule.hxx
+++ b/oox/inc/oox/ole/vbamodule.hxx
@@ -68,11 +68,26 @@ public:
/** Imports all records for this module until the MODULEEND record. */
void importDirRecords( BinaryInputStream& rDirStrm );
- /** Imports the Basic source code into the passed Basic library. */
- void importSourceCode(
+
+ /** Imports the VBA source code into the passed Basic library. */
+ void createAndImportModule(
StorageBase& rVbaStrg,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
+ /** Creates an empty Basic module in the passed Basic library. */
+ void createEmptyModule(
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
+
+private:
+ /** Reads and returns the VBA source code from the passed storage. */
+ ::rtl::OUString readSourceCode( StorageBase& rVbaStrg ) const;
+
+ /** Creates a new Basic module and inserts it into the passed Basic library. */
+ void createModule(
+ const ::rtl::OUString& rVBASourceCode,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxBasicLib,
+ const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxDocObjectNA ) const;
private:
::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
diff --git a/oox/inc/oox/ole/vbaproject.hxx b/oox/inc/oox/ole/vbaproject.hxx
index 1d2fca29dbab..e8d9aa7c0f5d 100644
--- a/oox/inc/oox/ole/vbaproject.hxx
+++ b/oox/inc/oox/ole/vbaproject.hxx
@@ -97,6 +97,18 @@ public:
/** Returns true, if the document contains the specified dialog. */
bool hasDialog( const ::rtl::OUString& rDialogName ) const;
+protected:
+ /** Registers a dummy module that will be created when the VBA project is
+ imported. */
+ void addDummyModule( const ::rtl::OUString& rName, sal_Int32 nType );
+ /** Creates all dummy modules in the document. */
+ void createDummyModules();
+
+ /** 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& );
VbaProject& operator=( const VbaProject& );
@@ -113,12 +125,18 @@ private:
/** Creates and returns the dialog library of the document used for import. */
::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
createDialogLibrary();
+
/** Imports the VBA code modules and forms. */
- void importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGraphicHelper, bool bDefaultColorBgr );
+ void importVba(
+ StorageBase& rVbaPrjStrg,
+ const GraphicHelper& rGraphicHelper,
+ bool bDefaultColorBgr );
/** Copies the entire VBA project storage to the passed document model. */
void copyStorage( StorageBase& rVbaPrjStrg );
private:
+ typedef ::std::map< ::rtl::OUString, sal_Int32 > DummyModuleMap;
+
::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >
mxGlobalFactory; /// Global service factory.
::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >
@@ -127,6 +145,7 @@ 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.
+ DummyModuleMap maDummyModules; /// Additional empty modules created on import.
const ::rtl::OUString maLibName; /// Name for Basic and dialog library used for import.
};
diff --git a/oox/inc/oox/xls/excelvbaproject.hxx b/oox/inc/oox/xls/excelvbaproject.hxx
new file mode 100755
index 000000000000..121e6a1667cd
--- /dev/null
+++ b/oox/inc/oox/xls/excelvbaproject.hxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * 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_XLS_EXCELVBAPROJECT_HXX
+#define OOX_XLS_EXCELVBAPROJECT_HXX
+
+#include "oox/ole/vbaproject.hxx"
+#include "oox/dllapi.h"
+
+namespace com { namespace sun { namespace star {
+ namespace sheet { class XSpreadsheetDocument; }
+} } }
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+/** Special implementation of the VBA project for the Excel filters. */
+class OOX_DLLPUBLIC ExcelVbaProject : public ::oox::ole::VbaProject
+{
+public:
+ 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 );
+
+ /** Generates VBA modules for sheets that do not specify a codename. */
+ void createMissingModules();
+
+protected:
+ /** Adds dummy modules for sheets without imported code name. */
+ virtual void prepareImport();
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
+ mxDocument;
+};
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
+
+#endif
diff --git a/oox/prj/d.lst b/oox/prj/d.lst
index ff13b324d65c..f656056b119e 100644
--- a/oox/prj/d.lst
+++ b/oox/prj/d.lst
@@ -36,6 +36,7 @@ mkdir: %_DEST%\inc%_EXT%\oox\xls
..\inc\oox\ole\vbaproject.hxx %_DEST%\inc%_EXT%\oox\ole\vbaproject.hxx
..\inc\oox\vml\vmldrawing.hxx %_DEST%\inc%_EXT%\oox\vml\vmldrawing.hxx
..\inc\oox\vml\vmlshape.hxx %_DEST%\inc%_EXT%\oox\vml\vmlshape.hxx
+..\inc\oox\xls\excelvbaproject.hxx %_DEST%\inc%_EXT%\oox\xls\excelvbaproject.hxx
dos: sh -c "if test %OS% = MACOSX; then create-bundle %_DEST%\lib%_EXT%\*.dylib; fi"
diff --git a/oox/source/ole/vbamodule.cxx b/oox/source/ole/vbamodule.cxx
index 9886f2cc5968..dbd5c9c02ced 100644
--- a/oox/source/ole/vbamodule.cxx
+++ b/oox/source/ole/vbamodule.cxx
@@ -128,18 +128,56 @@ void VbaModule::importDirRecords( BinaryInputStream& rDirStrm )
OSL_ENSURE( mnOffset < SAL_MAX_UINT32, "VbaModule::importDirRecords - missing module stream offset" );
}
-void VbaModule::importSourceCode( StorageBase& rVbaStrg,
- const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+void VbaModule::createAndImportModule( StorageBase& rVbaStrg, const Reference< XNameContainer >& rxBasicLib,
+ const Reference< XNameAccess >& rxDocObjectNA ) const
{
- if( (maName.getLength() == 0) || (maStreamName.getLength() == 0) || (mnOffset == SAL_MAX_UINT32) )
- return;
+ OUString aVBASourceCode = readSourceCode( rVbaStrg );
+ createModule( aVBASourceCode, rxBasicLib, rxDocObjectNA );
+}
+
+void VbaModule::createEmptyModule( const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ createModule( OUString(), rxBasicLib, rxDocObjectNA );
+}
- BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true );
- OSL_ENSURE( !aInStrm.isEof(), "VbaModule::importSourceCode - cannot open module stream" );
- // skip the 'performance cache' stored before the actual source code
- aInStrm.seek( mnOffset );
- // if stream is still valid, load the source code
- if( aInStrm.isEof() )
+// private --------------------------------------------------------------------
+
+OUString VbaModule::readSourceCode( StorageBase& rVbaStrg ) const
+{
+ OUStringBuffer aSourceCode;
+ if( (maStreamName.getLength() > 0) && (mnOffset != SAL_MAX_UINT32) )
+ {
+ BinaryXInputStream aInStrm( rVbaStrg.openInputStream( maStreamName ), true );
+ OSL_ENSURE( !aInStrm.isEof(), "VbaModule::readSourceCode - cannot open module stream" );
+ // skip the 'performance cache' stored before the actual source code
+ aInStrm.seek( mnOffset );
+ // if stream is still valid, load the source code
+ if( !aInStrm.isEof() )
+ {
+ // decompression starts at current stream position of aInStrm
+ VbaInputStream aVbaStrm( aInStrm );
+ // load the source code line-by-line, with some more processing
+ TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc );
+ while( !aVbaTextStrm.isEof() )
+ {
+ OUString aCodeLine = aVbaTextStrm.readLine();
+ if( !aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
+ {
+ // normal source code line
+ if( !mbExecutable )
+ aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) );
+ aSourceCode.append( aCodeLine ).append( sal_Unicode( '\n' ) );
+ }
+ }
+ }
+ }
+ return aSourceCode.makeStringAndClear();
+}
+
+void VbaModule::createModule( const OUString& rVBASourceCode,
+ const Reference< XNameContainer >& rxBasicLib, const Reference< XNameAccess >& rxDocObjectNA ) const
+{
+ if( maName.getLength() == 0 )
return;
// prepare the Basic module
@@ -162,7 +200,7 @@ void VbaModule::importSourceCode( StorageBase& rVbaStrg,
break;
case ModuleType::DOCUMENT:
aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "VBADocumentModule" ) );
- // get the VBA object associated to the document module
+ // get the VBA implementation object associated to the document module
if( rxDocObjectNA.is() ) try
{
aModuleInfo.ModuleObject.set( rxDocObjectNA->getByName( maName ), UNO_QUERY );
@@ -188,21 +226,8 @@ void VbaModule::importSourceCode( StorageBase& rVbaStrg,
append( maName.replace( ' ', '_' ) ).append( sal_Unicode( '\n' ) );
}
- // decompression starts at current stream position of aInStrm
- VbaInputStream aVbaStrm( aInStrm );
- // load the source code line-by-line, with some more processing
- TextInputStream aVbaTextStrm( aVbaStrm, meTextEnc );
- while( !aVbaTextStrm.isEof() )
- {
- OUString aCodeLine = aVbaTextStrm.readLine();
- // skip all 'Attribute' statements
- if( !aCodeLine.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "Attribute " ) ) )
- {
- if( !mbExecutable )
- aSourceCode.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Rem " ) );
- aSourceCode.append( aCodeLine ).append( sal_Unicode( '\n' ) );
- }
- }
+ // append passed VBA source code
+ aSourceCode.append( rVBASourceCode );
// close the subroutine named after the module
if( !mbExecutable )
@@ -225,7 +250,7 @@ void VbaModule::importSourceCode( StorageBase& rVbaStrg,
}
catch( Exception& )
{
- OSL_ENSURE( false, "VbaModule::importSourceCode - cannot insert module into library" );
+ OSL_ENSURE( false, "VbaModule::createModule - cannot insert module into library" );
}
}
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index deff066a5ed5..0f7e3cb8612a 100644
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -173,6 +173,67 @@ bool VbaProject::hasDialog( const OUString& rDialogName ) const
return mxDialogLib.is() && mxDialogLib->hasByName( rDialogName );
}
+// protected ------------------------------------------------------------------
+
+void VbaProject::addDummyModule( const OUString& rName, sal_Int32 nType )
+{
+ OSL_ENSURE( rName.getLength() > 0, "VbaProject::addDummyModule - missing module name" );
+ maDummyModules[ rName ] = nType;
+}
+
+void VbaProject::createDummyModules()
+{
+ /* !! HACK !! This function is called from old XLS filter only, must be
+ removed when this filter uses the OOX VBA import instead of the old SVX
+ VBA import.
+ */
+
+ // create empty dummy modules
+ typedef RefMap< OUString, VbaModule > VbaModuleMap;
+ VbaModuleMap aDummyModules;
+ for( DummyModuleMap::iterator aIt = maDummyModules.begin(), aEnd = maDummyModules.end(); aIt != aEnd; ++aIt )
+ {
+ OSL_ENSURE( !aDummyModules.has( aIt->first ), "VbaProject::createDummyModules - multiple modules with the same name" );
+ VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ];
+ rxModule.reset( new VbaModule( mxDocModel, aIt->first, RTL_TEXTENCODING_MS_1252, isImportVbaExecutable() ) );
+ rxModule->setType( aIt->second );
+ }
+
+ if( !aDummyModules.empty() ) try
+ {
+ // get the model factory and the basic library
+ Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
+ Reference< XNameContainer > xBasicLib( createBasicLibrary(), UNO_SET_THROW );
+
+ // try to get access to document objects related to code modules
+ Reference< XNameAccess > xDocObjectNA;
+ try
+ {
+ xDocObjectNA.set( xModelFactory->createInstance( CREATE_OUSTRING( "ooo.vba.VBAObjectModuleObjectProvider" ) ), UNO_QUERY );
+ }
+ catch( Exception& )
+ {
+ // not all documents support this
+ }
+
+ // create empty dummy modules
+ if( xBasicLib.is() )
+ aDummyModules.forEachMem( &VbaModule::createEmptyModule,
+ ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+void VbaProject::prepareImport()
+{
+}
+
+void VbaProject::finalizeImport()
+{
+}
+
// private --------------------------------------------------------------------
Reference< XLibraryContainer > VbaProject::getLibraryContainer( sal_Int32 nPropId )
@@ -231,6 +292,9 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
if( aDirStrm.isEof() )
return;
+ // virtual call, derived classes may do some preparations
+ prepareImport();
+
// read all records of the directory
rtl_TextEncoding eTextEnc = RTL_TEXTENCODING_MS_1252;
sal_uInt16 nModuleCount = 0;
@@ -345,17 +409,29 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
}
}
+ // create empty dummy modules
+ VbaModuleMap aDummyModules;
+ for( DummyModuleMap::iterator aIt = maDummyModules.begin(), aEnd = maDummyModules.end(); aIt != aEnd; ++aIt )
+ {
+ OSL_ENSURE( !aModules.has( aIt->first ) && !aDummyModules.has( aIt->first ), "VbaProject::importVba - multiple modules with the same name" );
+ VbaModuleMap::mapped_type& rxModule = aDummyModules[ aIt->first ];
+ rxModule.reset( new VbaModule( mxDocModel, aIt->first, eTextEnc, bExecutable ) );
+ rxModule->setType( aIt->second );
+ }
+
/* 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'
member. Do not create the Basic library, if there are no modules
specified. */
- if( !aModules.empty() ) try
+ if( !aModules.empty() || !aDummyModules.empty() ) try
{
// get the model factory and the basic library
Reference< XMultiServiceFactory > xModelFactory( mxDocModel, UNO_QUERY_THROW );
Reference< XNameContainer > xBasicLib( createBasicLibrary(), UNO_SET_THROW );
- // set library container to VBA compatibility mode
+ /* Set library container to VBA compatibility mode. This will create
+ the VBA Globals object and store it in the Basic manager of the
+ document. */
try
{
Reference< XVBACompatibility >( getLibraryContainer( PROP_BasicLibraries ), UNO_QUERY_THROW )->setVBACompatibilityMode( sal_True );
@@ -364,15 +440,6 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
{
}
- // create the VBAGlobals object, the model will store it in the Basic manager
- try
- {
- xModelFactory->createInstance( CREATE_OUSTRING( "ooo.vba.VBAGlobals" ) );
- }
- catch( Exception& )
- {
- }
-
// try to get access to document objects related to code modules
Reference< XNameAccess > xDocObjectNA;
try
@@ -384,10 +451,17 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
// not all documents support this
}
- // call Basic source code import for each module, boost::[c]ref enforces pass-by-ref
if( xBasicLib.is() )
- aModules.forEachMem( &VbaModule::importSourceCode,
- ::boost::ref( *xVbaStrg ), ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
+ {
+ // call Basic source code import for each module, boost::[c]ref enforces pass-by-ref
+ aModules.forEachMem( &VbaModule::createAndImportModule,
+ ::boost::ref( *xVbaStrg ), ::boost::cref( xBasicLib ),
+ ::boost::cref( xDocObjectNA ) );
+
+ // create empty dummy modules
+ aDummyModules.forEachMem( &VbaModule::createEmptyModule,
+ ::boost::cref( xBasicLib ), ::boost::cref( xDocObjectNA ) );
+ }
}
catch( Exception& )
{
@@ -402,7 +476,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
for( ::std::vector< OUString >::iterator aIt = aElements.begin(), aEnd = aElements.end(); aIt != aEnd; ++aIt )
{
// try to open the element as storage
- if( !aIt->equals( CREATE_OUSTRING( "VBA" ) ) )
+ if( !aIt->equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VBA" ) ) )
{
StorageRef xSubStrg = rVbaPrjStrg.openSubStorage( *aIt, false );
if( xSubStrg.get() ) try
@@ -425,6 +499,9 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
}
}
}
+
+ // virtual call, derived classes may do some more processing
+ finalizeImport();
}
void VbaProject::copyStorage( StorageBase& rVbaPrjStrg )
diff --git a/oox/source/xls/excelvbaproject.cxx b/oox/source/xls/excelvbaproject.cxx
new file mode 100755
index 000000000000..ee22dc8398ba
--- /dev/null
+++ b/oox/source/xls/excelvbaproject.cxx
@@ -0,0 +1,161 @@
+/*************************************************************************
+ *
+ * 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/xls/excelvbaproject.hxx"
+
+#include <list>
+#include <set>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/script/ModuleType.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <rtl/ustrbuf.hxx>
+#include "oox/helper/helper.hxx"
+#include "oox/helper/propertyset.hxx"
+#include "properties.hxx"
+
+namespace oox {
+namespace xls {
+
+// ============================================================================
+
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::document;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::sheet;
+using namespace ::com::sun::star::uno;
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+// ============================================================================
+
+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 ExcelVbaProject::createMissingModules()
+{
+ /* !! HACK !! This function is called from old XLS filter only, must be
+ removed when this filter uses the OOX VBA import instead of the old SVX
+ VBA import.
+ */
+
+ // collect and register all sheets without codenames
+ prepareImport();
+ // manually create the registered dummy modules
+ createDummyModules();
+}
+
+// protected ------------------------------------------------------------------
+
+namespace {
+
+struct SheetCodeNameInfo
+{
+ PropertySet maSheetProps; /// Property set of the sheet without codename.
+ OUString maPrefix; /// Prefix for the codename to be generated.
+
+ inline explicit SheetCodeNameInfo( PropertySet& rSheetProps, const OUString& rPrefix ) :
+ maSheetProps( rSheetProps ), maPrefix( rPrefix ) {}
+};
+
+typedef ::std::set< OUString > CodeNameSet;
+typedef ::std::list< SheetCodeNameInfo > SheetCodeNameInfoList;
+
+} // namespace
+
+void ExcelVbaProject::prepareImport()
+{
+ /* Check if the sheets have imported codenames. Generate new unused
+ codenames if not. */
+ if( mxDocument.is() ) try
+ {
+ // collect existing codenames (do not use them when creating new codenames)
+ CodeNameSet aUsedCodeNames;
+
+ // collect sheets without codenames
+ SheetCodeNameInfoList aCodeNameInfos;
+
+ // iterate over all imported sheets
+ Reference< XEnumerationAccess > xSheetsEA( mxDocument->getSheets(), UNO_QUERY_THROW );
+ Reference< XEnumeration > xSheetsEnum( xSheetsEA->createEnumeration(), UNO_SET_THROW );
+ // own try/catch for every sheet
+ while( xSheetsEnum->hasMoreElements() ) try
+ {
+ PropertySet aSheetProp( xSheetsEnum->nextElement() );
+ OUString aCodeName;
+ aSheetProp.getProperty( aCodeName, PROP_CodeName );
+ if( aCodeName.getLength() > 0 )
+ {
+ aUsedCodeNames.insert( aCodeName );
+ }
+ else
+ {
+ // TODO: once we have chart sheets we need a switch/case on sheet type ('SheetNNN' vs. 'ChartNNN')
+ aCodeNameInfos.push_back( SheetCodeNameInfo( aSheetProp, CREATE_OUSTRING( "Sheet" ) ) );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+
+ // create new codenames if sheets do not have one
+ for( SheetCodeNameInfoList::iterator aIt = aCodeNameInfos.begin(), aEnd = aCodeNameInfos.end(); aIt != aEnd; ++aIt )
+ {
+ // search for an unused codename
+ sal_Int32 nCounter = 1;
+ OUString aCodeName;
+ do
+ {
+ aCodeName = OUStringBuffer( aIt->maPrefix ).append( nCounter++ ).makeStringAndClear();
+ }
+ while( aUsedCodeNames.count( aCodeName ) > 0 );
+ aUsedCodeNames.insert( aCodeName );
+
+ // set codename at sheet
+ aIt->maSheetProps.setProperty( PROP_CodeName, aCodeName );
+
+ // tell base class to create a dummy module
+ addDummyModule( aCodeName, ModuleType::DOCUMENT );
+ }
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+// ============================================================================
+
+} // namespace xls
+} // namespace oox
diff --git a/oox/source/xls/makefile.mk b/oox/source/xls/makefile.mk
index cdb2e18c262d..b5ede953bbfe 100644
--- a/oox/source/xls/makefile.mk
+++ b/oox/source/xls/makefile.mk
@@ -59,6 +59,7 @@ SLOFILES = \
$(SLO)$/excelchartconverter.obj \
$(SLO)$/excelfilter.obj \
$(SLO)$/excelhandlers.obj \
+ $(SLO)$/excelvbaproject.obj \
$(SLO)$/externallinkbuffer.obj \
$(SLO)$/externallinkfragment.obj \
$(SLO)$/formulabase.obj \
diff --git a/oox/source/xls/workbookhelper.cxx b/oox/source/xls/workbookhelper.cxx
index 5684fbd8ae75..ceba5690004c 100644
--- a/oox/source/xls/workbookhelper.cxx
+++ b/oox/source/xls/workbookhelper.cxx
@@ -43,7 +43,6 @@
#include "properties.hxx"
#include "oox/helper/progressbar.hxx"
#include "oox/helper/propertyset.hxx"
-#include "oox/ole/vbaproject.hxx"
#include "oox/drawingml/theme.hxx"
#include "oox/xls/addressconverter.hxx"
#include "oox/xls/biffinputstream.hxx"
@@ -51,6 +50,7 @@
#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"
@@ -691,7 +691,7 @@ void WorkbookHelper::finalizeWorkbookImport()
StorageRef xVbaPrjStrg = mrBookData.getVbaProjectStorage();
if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
{
- ::oox::ole::VbaProject aVbaProject( getGlobalFactory(), getBaseFilter().getModel(), CREATE_OUSTRING( "Calc" ) );
+ ExcelVbaProject aVbaProject( getGlobalFactory(), getDocument() );
aVbaProject.importVbaProject( *xVbaPrjStrg, getBaseFilter().getGraphicHelper() );
}
}