summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-09-02 15:18:49 +0200
committerDaniel Rentz [dr] <daniel.rentz@oracle.com>2010-09-02 15:18:49 +0200
commit18df99d4dbb610e9300e146167127df491d2a4c1 (patch)
treeb29c5d02196e60585f8fb944e4589d4142555c41
parent8b4b42daa8b06dc095965e458105f669928693b6 (diff)
dr77: prepare creation of missing modules
-rwxr-xr-xoox/inc/oox/xls/excelvbaproject.hxx14
-rw-r--r--oox/source/ole/vbaproject.cxx2
-rwxr-xr-xoox/source/xls/excelvbaproject.cxx210
-rw-r--r--oox/source/xls/makefile.mk1
4 files changed, 34 insertions, 193 deletions
diff --git a/oox/inc/oox/xls/excelvbaproject.hxx b/oox/inc/oox/xls/excelvbaproject.hxx
index 490c1d6ad3a1..96dabd08b5d7 100755
--- a/oox/inc/oox/xls/excelvbaproject.hxx
+++ b/oox/inc/oox/xls/excelvbaproject.hxx
@@ -48,23 +48,9 @@ public:
const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext,
const ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >& rxDocument );
- /** Attaches all document and sheet events to existing VBA macros. */
- void attachToEvents();
-
protected:
/** Adds dummy modules for sheets without imported code name. */
virtual void prepareImport();
- /** Attaches document and sheet events to macros. */
- virtual void finalizeImport();
-
-private:
- /** Attaches VBA macros to all supported document events. */
- void attachToDocumentEvents( const ::rtl::OUString& rCodeName );
-
- /** Attaches VBA macros to all supported sheet events. */
- void attachToSheetEvents(
- const ::com::sun::star::uno::Reference< ::com::sun::star::document::XEventsSupplier >& rxEventsSupp,
- const ::rtl::OUString& rCodeName );
private:
::com::sun::star::uno::Reference< ::com::sun::star::sheet::XSpreadsheetDocument >
diff --git a/oox/source/ole/vbaproject.cxx b/oox/source/ole/vbaproject.cxx
index d7c2c759b47c..0136a223ff6a 100644
--- a/oox/source/ole/vbaproject.cxx
+++ b/oox/source/ole/vbaproject.cxx
@@ -413,7 +413,7 @@ void VbaProject::importVba( StorageBase& rVbaPrjStrg, const GraphicHelper& rGrap
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" );
+ 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 );
diff --git a/oox/source/xls/excelvbaproject.cxx b/oox/source/xls/excelvbaproject.cxx
index 8b072d282702..8061f1019d96 100755
--- a/oox/source/xls/excelvbaproject.cxx
+++ b/oox/source/xls/excelvbaproject.cxx
@@ -33,6 +33,7 @@
#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"
@@ -48,6 +49,7 @@ 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;
@@ -62,66 +64,21 @@ ExcelVbaProject::ExcelVbaProject( const Reference< XComponentContext >& rxContex
{
}
-void ExcelVbaProject::attachToEvents()
-{
- // do nothing is code is not executable
- if( !isImportVbaExecutable() )
- return;
-
- // document events
- PropertySet aDocProp( mxDocument );
- OUString aCodeName;
- aDocProp.getProperty( aCodeName, PROP_CodeName );
- attachToDocumentEvents( aCodeName );
-
- // sheet events
- if( mxDocument.is() ) try
- {
- 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
- {
- // TODO: once we have chart sheets we need a switch/case on sheet type
- Reference< XEventsSupplier > xEventsSupp( xSheetsEnum->nextElement(), UNO_QUERY_THROW );
- PropertySet aSheetProp( xEventsSupp );
- aSheetProp.getProperty( aCodeName, PROP_CodeName );
- attachToSheetEvents( xEventsSupp, aCodeName );
- }
- catch( Exception& )
- {
- }
- }
- catch( Exception& )
- {
- }
-}
-
// protected ------------------------------------------------------------------
namespace {
-typedef ::std::set< OUString > CodeNameSet;
-typedef ::std::list< PropertySet > SheetPropertySetList;
-
-void lclGenerateMissingCodeNames( CodeNameSet& rUsedCodeNames, SheetPropertySetList& rSheetsWithout, const OUString& rCodeNamePrefix )
+struct SheetCodeNameInfo
{
- sal_Int32 nCounter = 1;
- for( SheetPropertySetList::iterator aIt = rSheetsWithout.begin(), aEnd = rSheetsWithout.end(); aIt != aEnd; ++aIt )
- {
- // search for an unused codename
- OUString aCodeName;
- do
- {
- aCodeName = OUStringBuffer( rCodeNamePrefix ).append( nCounter++ ).makeStringAndClear();
- }
- while( rUsedCodeNames.count( aCodeName ) > 0 );
- rUsedCodeNames.insert( aCodeName );
+ PropertySet maSheetProps; /// Property set of the sheet without codename.
+ OUString maPrefix; /// Prefix for the codename to be generated.
- // set codename at sheet
- aIt->setProperty( PROP_CodeName, aCodeName );
- }
-}
+ inline explicit SheetCodeNameInfo( PropertySet& rSheetProps, const OUString& rPrefix ) :
+ maSheetProps( rSheetProps ), maPrefix( rPrefix ) {}
+};
+
+typedef ::std::set< OUString > CodeNameSet;
+typedef ::std::list< SheetCodeNameInfo > SheetCodeNameInfoList;
} // namespace
@@ -134,8 +91,8 @@ void ExcelVbaProject::prepareImport()
// collect existing codenames (do not use them when creating new codenames)
CodeNameSet aUsedCodeNames;
- // collect common sheets and chart sheets without codenames
- SheetPropertySetList aSheetsWithout, aChartsWithout;
+ // collect sheets without codenames
+ SheetCodeNameInfoList aCodeNameInfos;
// iterate over all imported sheets
Reference< XEnumerationAccess > xSheetsEA( mxDocument->getSheets(), UNO_QUERY_THROW );
@@ -153,7 +110,7 @@ void ExcelVbaProject::prepareImport()
else
{
// TODO: once we have chart sheets we need a switch/case on sheet type ('SheetNNN' vs. 'ChartNNN')
- aSheetsWithout.push_back( aSheetProp );
+ aCodeNameInfos.push_back( SheetCodeNameInfo( aSheetProp, CREATE_OUSTRING( "Sheet" ) ) );
}
}
catch( Exception& )
@@ -161,131 +118,28 @@ void ExcelVbaProject::prepareImport()
}
// create new codenames if sheets do not have one
- lclGenerateMissingCodeNames( aUsedCodeNames, aSheetsWithout, CREATE_OUSTRING( "Sheet" ) );
- lclGenerateMissingCodeNames( aUsedCodeNames, aChartsWithout, CREATE_OUSTRING( "Chart" ) );
- }
- catch( Exception& )
- {
- }
-}
-
-void ExcelVbaProject::finalizeImport()
-{
- attachToEvents();
-}
-
-// private --------------------------------------------------------------------
-
-void ExcelVbaProject::attachToDocumentEvents( const OUString& rCodeName )
-{
- if( (rCodeName.getLength() == 0) || !hasModule( rCodeName ) )
- return;
-
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnLoad" ), rCodeName, CREATE_OUSTRING( "Workbook_Open" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnFocus" ), rCodeName, CREATE_OUSTRING( "Workbook_Activate" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnUnfocus" ), rCodeName, CREATE_OUSTRING( "Workbook_Deactivate" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnSave" ), rCodeName, CREATE_OUSTRING( "Workbook_BeforeSave" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO False, False" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnSaveAs" ), rCodeName, CREATE_OUSTRING( "Workbook_BeforeSave" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO True, False" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnSaveDone" ), rCodeName, CREATE_OUSTRING( "Workbook_AfterSave" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO True" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnSaveAsDone" ), rCodeName, CREATE_OUSTRING( "Workbook_AfterSave" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO True" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnSaveFailed" ), rCodeName, CREATE_OUSTRING( "Workbook_AfterSave" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO False" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnSaveAsFailed" ), rCodeName, CREATE_OUSTRING( "Workbook_AfterSave" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO False" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnPrint" ), rCodeName, CREATE_OUSTRING( "Workbook_BeforePrint" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO False" ) );
- attachMacroToDocumentEvent( CREATE_OUSTRING( "OnPrepareUnload" ), rCodeName, CREATE_OUSTRING( "Workbook_BeforeClose" ), OUString(), OUString(), CREATE_OUSTRING( "\t$MACRO False" ) );
-}
-
-void ExcelVbaProject::attachToSheetEvents( const Reference< XEventsSupplier >& rxEventsSupp, const OUString& rCodeName )
-{
- if( !rxEventsSupp.is() || (rCodeName.getLength() == 0) || !hasModule( rCodeName ) )
- return;
-
- // attach macros to simple sheet events directly
- attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnFocus" ), rCodeName, CREATE_OUSTRING( "Worksheet_Activate" ) );
- attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnUnfocus" ), rCodeName, CREATE_OUSTRING( "Worksheet_Deactivate" ) );
- attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnCalculate" ), rCodeName, CREATE_OUSTRING( "Worksheet_Calculate" ) );
-
- /* Attach macros to complex sheet events. The events pass a cell range or
- a collection of cell ranges depending on the event type and sheet
- selection. The generated proxy macros need to convert these UNO renges
- to VBA compatible ranges.
- */
-
-#define VBA_MACRONAME_RANGECONV "Local_GetVbaRangeFromUnoRange"
-#define VBA_MACRONAME_TARGETCONV "Local_GetVbaTargetFromUnoTarget"
-
- /* If this variable turns to true, the macros that convert UNO cell ranges
- to VBA Range objects have to be inserted.
- */
- bool bNeedsTargetHelper = false;
-
- /* Insert the proxy macros attached to sheet events that notify something
- has changed (changed selection and changed cell contents). These events
- cannot be cancelled. The proxy macro converts the passed UNO cell range
- or collection of cell ranges to a VBA Range object, and calls the VBA
- event handler.
- */
- OUString aChangeProxyArgs = CREATE_OUSTRING( "ByVal unoTarget As Object" );
- OUString aChangeProxyCode = CREATE_OUSTRING(
- "\tDim vbaTarget As Range : Set vbaTarget = " VBA_MACRONAME_TARGETCONV "( unoTarget )\n"
- "\tIf Not vbaTarget Is Nothing Then $MACRO vbaTarget" );
- bNeedsTargetHelper |= attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnChange" ), rCodeName, CREATE_OUSTRING( "Worksheet_Change" ), aChangeProxyArgs, OUString(), aChangeProxyCode );
- bNeedsTargetHelper |= attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnSelect" ), rCodeName, CREATE_OUSTRING( "Worksheet_SelectionChange" ), aChangeProxyArgs, OUString(), aChangeProxyCode );
+ sal_Int32 nCounter = 1;
+ for( SheetCodeNameInfoList::iterator aIt = aCodeNameInfos.begin(), aEnd = aCodeNameInfos.end(); aIt != aEnd; ++aIt )
+ {
+ // search for an unused codename
+ OUString aCodeName;
+ do
+ {
+ aCodeName = OUStringBuffer( aIt->maPrefix ).append( nCounter++ ).makeStringAndClear();
+ }
+ while( aUsedCodeNames.count( aCodeName ) > 0 );
+ aUsedCodeNames.insert( aCodeName );
- /* Insert the proxy macros attached to sheet events that notify an ongoing
- mouse click event (double click and right click). These events can be
- cancelled by returning false (in VBA: as a Boolean output parameter, in
- UNO: as return value of the Basic function). The proxy macro converts
- the passed UNO cell range or collection of cell ranges to a VBA Range
- object, calls the VBA event handler, and returns the Boolean value
- provided by the VBA event handler.
- */
- OUString aClickProxyArgs = CREATE_OUSTRING( "ByVal unoTarget As Object" );
- OUString aClickProxyRetT = CREATE_OUSTRING( "Boolean" );
- OUString aClickProxyCode = CREATE_OUSTRING(
- "\tDim Cancel As Boolean : Cancel = False\n"
- "\tDim vbaTarget As Range : Set vbaTarget = " VBA_MACRONAME_TARGETCONV "( unoTarget )\n"
- "\tIf Not vbaTarget Is Nothing Then $MACRO vbaTarget, Cancel\n"
- "\t$PROXY = Cancel" );
- bNeedsTargetHelper |= attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnDoubleClick" ), rCodeName, CREATE_OUSTRING( "Worksheet_BeforeDoubleClick" ), aClickProxyArgs, aClickProxyRetT, aClickProxyCode );
- bNeedsTargetHelper |= attachMacroToEvent( rxEventsSupp, CREATE_OUSTRING( "OnRightClick" ), rCodeName, CREATE_OUSTRING( "Worksheet_BeforeRightClick" ), aClickProxyArgs, aClickProxyRetT, aClickProxyCode );
+ // set codename at sheet
+ aIt->maSheetProps.setProperty( PROP_CodeName, aCodeName );
- if( bNeedsTargetHelper )
+ // tell base class to create a dummy module
+ addDummyModule( aCodeName, ModuleType::DOCUMENT );
+ }
+ }
+ catch( Exception& )
{
- /* Generate a helper function that converts a
- com.sun.star.sheet.SheetCellRange object to a VBA Range object.
- */
- OUString aRangeConvName = CREATE_OUSTRING( VBA_MACRONAME_RANGECONV );
- OUString aRangeConvArgs = CREATE_OUSTRING( "ByVal unoRange As com.sun.star.sheet.SheetCellRange" );
- OUString aRangeConvRetT = CREATE_OUSTRING( "Range" );
- OUString aRangeConvCode = CREATE_OUSTRING(
- "\tDim unoAddress As com.sun.star.table.CellRangeAddress : Set unoAddress = unoRange.RangeAddress\n"
- "\tDim vbaSheet As Worksheet : Set vbaSheet = Application.ThisWorkbook.Sheets( unoAddress.Sheet + 1 )\n"
- "\tSet $MACRO = vbaSheet.Range( vbaSheet.Cells( unoAddress.StartRow + 1, unoAddress.StartColumn + 1 ), vbaSheet.Cells( unoAddress.EndRow + 1, unoAddress.EndColumn + 1 ) )" );
- insertMacro( rCodeName, aRangeConvName, aRangeConvArgs, aRangeConvRetT, aRangeConvCode );
-
- /* Generate a helper function that converts a generic range selection
- object (com.sun.star.sheet.SheetCellRange or
- com.sun.star.sheet.SheetCellRanges) to a VBA Range object.
- */
- OUString aTargetConvName = CREATE_OUSTRING( VBA_MACRONAME_TARGETCONV );
- OUString aTargetConvArgs = CREATE_OUSTRING( "ByVal unoTarget As Object" );
- OUString aTargetConvRetT = CREATE_OUSTRING( "Range" );
- OUString aTargetConvCode = CREATE_OUSTRING(
- "\tDim vbaTarget As Range\n"
- "\tIf unoTarget.supportsService( \"com.sun.star.sheet.SheetCellRange\" ) Then\n"
- "\t\tSet vbaTarget = " VBA_MACRONAME_RANGECONV "( unoTarget )\n"
- "\tElseIf unoTarget.supportsService( \"com.sun.star.sheet.SheetCellRanges\" ) Then\n"
- "\t\tDim unoRangeEnum As Object : Set unoRangeEnum = unoTarget.createEnumeration\n"
- "\t\tIf unoRangeEnum.hasMoreElements Then Set vbaTarget = " VBA_MACRONAME_RANGECONV "( unoRangeEnum.nextElement )\n"
- "\t\tWhile unoRangeEnum.hasMoreElements\n"
- "\t\t\tSet vbaTarget = Application.Union( vbaTarget, " VBA_MACRONAME_RANGECONV "( unoRangeEnum.nextElement ) )\n"
- "\t\tWend\n"
- "\tEnd If\n"
- "\tSet $MACRO = vbaTarget" );
- insertMacro( rCodeName, aTargetConvName, aTargetConvArgs, aTargetConvRetT, aTargetConvCode );
}
-#undef VBA_MACRONAME_RANGECONV
-#undef VBA_MACRONAME_TARGETCONV
}
// ============================================================================
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 \