diff options
51 files changed, 1669 insertions, 467 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 304a9d1df0f7..5c4685223281 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -161,6 +161,9 @@ namespace com { namespace sun { namespace star { namespace embed { class XEmbeddedObject; } + namespace script { namespace vba { + class XVBAEventProcessor; + } } namespace sheet { struct TablePageBreakData; } @@ -334,6 +337,9 @@ private: Timer aTrackTimer; + com::sun::star::uno::Reference< com::sun::star::script::vba::XVBAEventProcessor > + mxVbaEvents; + public: ScTabOpList aTableOpList; // list of ScInterpreterTableOpParams currently in use ScInterpreterTableOpParams aLastTableOpParams; // remember last params @@ -739,7 +745,8 @@ public: const ScSheetEvents* GetSheetEvents( SCTAB nTab ) const; void SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew ); - bool HasSheetEventScript( sal_Int32 nEvent ) const; // on any sheet + bool HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents = false ) const; + bool HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents = false ) const; // on any sheet BOOL HasCalcNotification( SCTAB nTab ) const; void SetCalcNotification( SCTAB nTab ); @@ -1784,6 +1791,11 @@ public: void GetSortParam( ScSortParam& rParam, SCTAB nTab ); void SetSortParam( ScSortParam& rParam, SCTAB nTab ); + inline void SetVbaEventProcessor( const com::sun::star::uno::Reference< com::sun::star::script::vba::XVBAEventProcessor >& rxVbaEvents ) + { mxVbaEvents = rxVbaEvents; } + inline com::sun::star::uno::Reference< com::sun::star::script::vba::XVBAEventProcessor > + GetVbaEventProcessor() const { return mxVbaEvents; } + /** Should only be GRAM_PODF or GRAM_ODFF. */ void SetStorageGrammar( formula::FormulaGrammar::Grammar eGrammar ); formula::FormulaGrammar::Grammar GetStorageGrammar() const diff --git a/sc/inc/scextopt.hxx b/sc/inc/scextopt.hxx index d7586fb8df95..ad3fd4b1b51e 100644 --- a/sc/inc/scextopt.hxx +++ b/sc/inc/scextopt.hxx @@ -115,13 +115,11 @@ public: ScExtTabSettings& GetOrCreateTabSettings( SCTAB nTab ); /** Returns the number of sheet codenames. */ - size_t GetCodeNameCount() const; + SCTAB GetCodeNameCount() const; /** Returns the specified codename (empty string = no codename). */ - const String& GetCodeName( size_t nIdx ) const; + const String& GetCodeName( SCTAB nTab ) const; /** Appends a codename for a sheet. */ - void AppendCodeName( const String& rCodeName ); - void SetCodeName( const String& rCodeName, size_t nIdx ); - void DeleteCodeName( size_t nIdx ); + void SetCodeName( SCTAB nTab, const String& rCodeName ); private: ::std::auto_ptr< ScExtDocOptionsImpl > mxImpl; diff --git a/sc/inc/sheetevents.hxx b/sc/inc/sheetevents.hxx index 8f52efb990f7..bb27f5cf2068 100755..100644 --- a/sc/inc/sheetevents.hxx +++ b/sc/inc/sheetevents.hxx @@ -59,6 +59,8 @@ public: void SetScript(sal_Int32 nEvent, const rtl::OUString* pNew); static rtl::OUString GetEventName(sal_Int32 nEvent); + static sal_Int32 GetVbaSheetEventId(sal_Int32 nEvent); + static sal_Int32 GetVbaDocumentEventId(sal_Int32 nEvent); }; #endif diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index e8ea10f7cf52..d2c99c75a95e 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -50,6 +50,7 @@ #include <tools/tenccvt.hxx> #include <tools/list.hxx> #include <rtl/crc.h> +#include <basic/basmgr.hxx> #include "document.hxx" #include "table.hxx" @@ -93,7 +94,8 @@ #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" -#include <basic/basmgr.hxx> + +using namespace com::sun::star; // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and // dtor plus helpers are convenient. @@ -1118,11 +1120,11 @@ ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, String sCodeName; String sSource; - com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer(); - com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xLib; + uno::Reference< script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer(); + uno::Reference< container::XNameContainer > xLib; if( xLibContainer.is() ) { - com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName ); + uno::Any aLibAny = xLibContainer->getByName( aLibName ); aLibAny >>= xLib; } diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 4928ade0f13d..8fea4b8af2b9 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -30,6 +30,7 @@ // INCLUDE --------------------------------------------------------------- +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include "scitems.hxx" #include <editeng/langitem.hxx> #include <svl/srchitem.hxx> @@ -88,7 +89,6 @@ #include <memory> using namespace com::sun::star; -using ::std::auto_ptr; //------------------------------------------------------------------------ @@ -512,15 +512,35 @@ void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew ) pTab[nTab]->SetSheetEvents( pNew ); } -bool ScDocument::HasSheetEventScript( sal_Int32 nEvent ) const +bool ScDocument::HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVbaEvents ) const { - for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) - if (pTab[nTab]) + if (pTab[nTab]) + { + // check if any event handler script has been configured + const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents(); + if ( pEvents && pEvents->GetScript( nEvent ) ) + return true; + // check if VBA event handlers exist + if (bWithVbaEvents && mxVbaEvents.is()) try { - const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents(); - if ( pEvents && pEvents->GetScript( nEvent ) ) + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= nTab; + if (mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ) || + mxVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent ), uno::Sequence< uno::Any >() )) return true; } + catch( uno::Exception& ) + { + } + } + return false; +} + +bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent, bool bWithVbaEvents ) const +{ + for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) + if (HasSheetEventScript( nTab, nEvent, bWithVbaEvents )) + return true; return false; } diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx index 97aae44f1a7b..d77dc1041d9c 100644 --- a/sc/source/core/data/documen7.cxx +++ b/sc/source/core/data/documen7.cxx @@ -454,7 +454,7 @@ void ScDocument::TrackFormulas( ULONG nHintId ) { erBEEPER(); // outside the loop, check if any sheet has a "calculate" event script - bool bCalcEvent = HasSheetEventScript( SC_SHEETEVENT_CALCULATE ); + bool bCalcEvent = HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ); SvtBroadcaster* pBC; ScFormulaCell* pTrack; ScFormulaCell* pNext; diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index a4f8833f6caa..1efe32446eef 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -51,7 +51,7 @@ #include <tools/tenccvt.hxx> #include <com/sun/star/text/WritingMode2.hpp> -#include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> #include <com/sun/star/sheet/TablePageBreakData.hpp> #include "document.hxx" @@ -5259,8 +5259,8 @@ bool ScDocument::IsInVBAMode() const bool bResult = false; if ( pShell ) { - com::sun::star::uno::Reference< com::sun::star::script::XVBACompat > xVBA( pShell->GetBasicContainer(), com::sun::star::uno::UNO_QUERY ); - bResult = xVBA->getVBACompatModeOn(); + com::sun::star::uno::Reference< com::sun::star::script::vba::XVBACompatibility > xVBA( pShell->GetBasicContainer(), com::sun::star::uno::UNO_QUERY ); + bResult = xVBA.is() && xVBA->getVBACompatibilityMode(); } return bResult; } diff --git a/sc/source/core/data/sheetevents.cxx b/sc/source/core/data/sheetevents.cxx index e9e430ef85d9..e1875b5db15b 100755..100644 --- a/sc/source/core/data/sheetevents.cxx +++ b/sc/source/core/data/sheetevents.cxx @@ -33,9 +33,9 @@ // INCLUDE --------------------------------------------------------------- -#include <tools/debug.hxx> - #include "sheetevents.hxx" +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <tools/debug.hxx> // ----------------------------------------------------------------------- @@ -61,6 +61,37 @@ rtl::OUString ScSheetEvents::GetEventName(sal_Int32 nEvent) return rtl::OUString::createFromAscii(aEventNames[nEvent]); } +// static +sal_Int32 ScSheetEvents::GetVbaSheetEventId(sal_Int32 nEvent) +{ + using namespace ::com::sun::star::script::vba::VBAEventId; + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return NO_EVENT; + } + + static const sal_Int32 nVbaEventIds[] = + { + WORKSHEET_ACTIVATE, // SC_SHEETEVENT_FOCUS + WORKSHEET_DEACTIVATE, // SC_SHEETEVENT_UNFOCUS + WORKSHEET_SELECTIONCHANGE, // SC_SHEETEVENT_SELECT + WORKSHEET_BEFOREDOUBLECLICK, // SC_SHEETEVENT_DOUBLECLICK + WORKSHEET_BEFORERIGHTCLICK, // SC_SHEETEVENT_RIGHTCLICK + WORKSHEET_CHANGE, // SC_SHEETEVENT_CHANGE + WORKSHEET_CALCULATE // SC_SHEETEVENT_CALCULATE + }; + return nVbaEventIds[nEvent]; +} + +// static +sal_Int32 ScSheetEvents::GetVbaDocumentEventId(sal_Int32 nEvent) +{ + using namespace ::com::sun::star::script::vba::VBAEventId; + sal_Int32 nSheetEventId = GetVbaSheetEventId(nEvent); + return (nSheetEventId != NO_EVENT) ? (nSheetEventId + USERDEFINED_START) : NO_EVENT; +} + // ----------------------------------------------------------------------- ScSheetEvents::ScSheetEvents() : diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 87561abf1513..baaabd3a8c8f 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -28,69 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - -//------------------------------------------------------------------------ - -#ifdef WIN - -// SFX -#define _SFXAPPWIN_HXX -#define _SFX_SAVEOPT_HXX -//#define _SFX_CHILDWIN_HXX *** -#define _SFXCTRLITEM_HXX -#define _SFXPRNMON_HXX -#define _INTRO_HXX -#define _SFXMSGDESCR_HXX -#define _SFXMSGPOOL_HXX -#define _SFXFILEDLG_HXX -#define _PASSWD_HXX -#define _SFXTBXCTRL_HXX -#define _SFXSTBITEM_HXX -#define _SFXMNUITEM_HXX -#define _SFXIMGMGR_HXX -#define _SFXTBXMGR_HXX -#define _SFXSTBMGR_HXX -#define _SFX_MINFITEM_HXX -#define _SFXEVENT_HXX - -//#define _SI_HXX -//#define SI_NODRW -#define _SI_DLL_HXX -#define _SIDLL_HXX -#define _SI_NOITEMS -#define _SI_NOOTHERFORMS -#define _SI_NOSBXCONTROLS -#define _SINOSBXCONTROLS -#define _SI_NODRW // -#define _SI_NOCONTROL -#define _VCBRW_HXX -#define _VCTRLS_HXX -//#define _VCSBX_HXX -#define _VCONT_HXX -#define _VDRWOBJ_HXX -#define _VCATTR_HXX - - -#define _SVX_DAILDLL_HXX -#define _SVX_HYPHEN_HXX -#define _SVX_IMPGRF_HXX -#define _SVX_OPTITEMS_HXX -#define _SVX_OPTGERL_HXX -#define _SVX_OPTSAVE_HXX -#define _SVX_OPTSPELL_HXX -#define _SVX_OPTPATH_HXX -#define _SVX_OPTLINGU_HXX -#define _SVX_RULER_HXX -#define _SVX_RULRITEM_HXX -#define _SVX_SPLWRAP_HXX -#define _SVX_SPLDLG_HXX -#define _SVX_THESDLG_HXX - -#endif //WIN - -// INCLUDE --------------------------------------------------------------- - #include "scitems.hxx" #include <svx/algitem.hxx> #include <unotools/textsearch.hxx> @@ -115,8 +52,6 @@ #include "sheetevents.hxx" #include "segmenttree.hxx" -// STATIC DATA ----------------------------------------------------------- - // ----------------------------------------------------------------------- ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index 2cf2d8f580c0..458629979172 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -420,7 +420,7 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) } -void ExcTable::FillAsTable( size_t nCodeNameIdx ) +void ExcTable::FillAsTable( SCTAB nCodeNameIdx ) { InitializeTable( mnScTab ); @@ -550,7 +550,7 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) Add( new ExcEof ); } -void ExcTable::FillAsXmlTable( size_t nCodeNameIdx ) +void ExcTable::FillAsXmlTable( SCTAB nCodeNameIdx ) { RootData& rR = GetOldRoot(); @@ -640,7 +640,7 @@ void ExcTable::FillAsXmlTable( size_t nCodeNameIdx ) } -void ExcTable::FillAsEmptyTable( size_t nCodeNameIdx ) +void ExcTable::FillAsEmptyTable( SCTAB nCodeNameIdx ) { InitializeTable( mnScTab ); @@ -723,7 +723,7 @@ void ExcDocument::ReadDoc( void ) aHeader.FillAsHeader( maBoundsheetList ); SCTAB nScTab = 0, nScTabCount = GetTabInfo().GetScTabCount(); - size_t nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount(); + SCTAB nCodeNameIdx = 0, nCodeNameCount = GetExtDocOptions().GetCodeNameCount(); for( ; nScTab < nScTabCount; ++nScTab ) { diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index 9608804da9f9..d75a0e669603 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -56,7 +56,6 @@ #include <svx/xflclit.hxx> #include <filter/msfilter/svxmsbas.hxx> #include <basic/basmgr.hxx> -#include <oox/xls/excelvbaproject.hxx> #include <vcl/graph.hxx> #include <vcl/bmpacc.hxx> @@ -243,17 +242,6 @@ void ImportExcel8::ReadBasic( void ) { SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg ); bool bAsComment = !bLoadExecutable; - if ( !bAsComment ) - { - uno::Any aGlobs; - uno::Sequence< uno::Any > aArgs(1); - aArgs[ 0 ] <<= pShell->GetModel(); - aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); - pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); - BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); - if ( pAppMgr ) - pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); - } aBasicImport.Import( EXC_STORAGE_VBA_PROJECT, EXC_STORAGE_VBA, bAsComment ); } } @@ -292,8 +280,6 @@ void ImportExcel8::PostDocLoad( void ) // read doc info (no docshell while pasting from clipboard) LoadDocumentProperties(); - // attach document events to VBA macros - AttachDocumentEvents(); // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available // when formula cells are calculated, for the GETPIVOTDATA function. @@ -318,21 +304,6 @@ void ImportExcel8::LoadDocumentProperties() } } -void ImportExcel8::AttachDocumentEvents() -{ - SfxObjectShell* pShell = GetDocShell(); - if( HasBasic() && pShell ) - { - uno::Reference< lang::XMultiServiceFactory > xGlobalFactory = ::comphelper::getProcessServiceFactory(); - uno::Reference< sheet::XSpreadsheetDocument > xDocument( pShell->GetModel(), uno::UNO_QUERY ); - if( xGlobalFactory.is() && xDocument.is() ) - { - ::oox::xls::VbaProject aVbaProject( xGlobalFactory, xDocument ); - aVbaProject.attachToEvents(); - } - } -} - //___________________________________________________________________ // autofilter diff --git a/sc/source/filter/excel/xiname.cxx b/sc/source/filter/excel/xiname.cxx index 70ff46a0d741..5d21d91c9f53 100644 --- a/sc/source/filter/excel/xiname.cxx +++ b/sc/source/filter/excel/xiname.cxx @@ -132,7 +132,8 @@ XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) : if( nXclTab != EXC_NAME_GLOBAL ) { sal_uInt16 nUsedTab = (GetBiff() == EXC_BIFF8) ? nXclTab : nExtSheet; - maScName.Append( '_' ).Append( String::CreateFromInt32( nUsedTab ) ); + // #163146# do not rename sheet-local names by default, this breaks VBA scripts +// maScName.Append( '_' ).Append( String::CreateFromInt32( nUsedTab ) ); // TODO: may not work for BIFF5, handle skipped sheets (all BIFF) mnScTab = static_cast< SCTAB >( nUsedTab - 1 ); } @@ -208,7 +209,8 @@ XclImpName::XclImpName( XclImpStream& rStrm, sal_uInt16 nXclNameIdx ) : // 4) *** create a defined name in the Calc document *** ------------------ - if( pTokArr && (bBuiltIn || !::get_flag( nFlags, EXC_NAME_HIDDEN )) && !mbVBName ) + // #163146# do not ignore hidden names (may be regular names created by VBA scripts) + if( pTokArr /*&& (bBuiltIn || !::get_flag( nFlags, EXC_NAME_HIDDEN ))*/ && !mbVBName ) { // create the Calc name data ScRangeData* pData = new ScRangeData( GetDocPtr(), maScName, *pTokArr, ScAddress(), nNameType ); diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx index 3fd2650cf2ff..5f8bcbd481e5 100644 --- a/sc/source/filter/excel/xiroot.cxx +++ b/sc/source/filter/excel/xiroot.cxx @@ -289,7 +289,7 @@ void XclImpRoot::ReadCodeName( XclImpStream& rStrm, bool bGlobals ) } else { - GetExtDocOptions().AppendCodeName( aName ); + GetExtDocOptions().SetCodeName( GetCurrScTab(), aName ); GetDoc().SetCodeName( GetCurrScTab(), aName ); } } diff --git a/sc/source/filter/excel/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx index bb77fac2be73..153a5d5ed3cc 100644 --- a/sc/source/filter/excel/xlescher.cxx +++ b/sc/source/filter/excel/xlescher.cxx @@ -36,8 +36,8 @@ #include "document.hxx" #include "xestream.hxx" #include "xistream.hxx" -#include "xltools.hxx" #include "xlroot.hxx" +#include "xltools.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Reference; diff --git a/sc/source/filter/inc/excdoc.hxx b/sc/source/filter/inc/excdoc.hxx index f00e8d091590..5da6a5d38d83 100644 --- a/sc/source/filter/inc/excdoc.hxx +++ b/sc/source/filter/inc/excdoc.hxx @@ -69,7 +69,7 @@ private: // pRec mit new anlegen und vergessen, delete macht ExcTable selber! void Add( XclExpRecordBase* pRec ); - void FillAsXmlTable( size_t nCodeNameIdx ); + void FillAsXmlTable( SCTAB nCodeNameIdx ); public: ExcTable( const XclExpRoot& rRoot ); @@ -77,8 +77,8 @@ public: ~ExcTable(); void FillAsHeader( ExcBoundsheetList& rBoundsheetList ); - void FillAsTable( size_t nCodeNameIdx ); - void FillAsEmptyTable( size_t nCodeNameIdx ); + void FillAsTable( SCTAB nCodeNameIdx ); + void FillAsEmptyTable( SCTAB nCodeNameIdx ); void Write( XclExpStream& ); void WriteXml( XclExpXmlStream& ); diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx index 5b2bbe2e7b5d..7e4cca15dfe1 100644 --- a/sc/source/filter/inc/excimp8.hxx +++ b/sc/source/filter/inc/excimp8.hxx @@ -81,7 +81,6 @@ protected: private: void LoadDocumentProperties(); - void AttachDocumentEvents(); }; diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index b34abb29443c..ca5403e3b18d 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -4340,7 +4340,7 @@ void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& uno::Reference <container::XNameAccess> xCodeNameAccess; DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); - if( pDoc ) + if( pDoc && pDoc->IsInVBAMode() ) { xCodeNameAccess = new XMLCodeNameProvider( pDoc ); if( xCodeNameAccess.is() && xCodeNameAccess->hasElements() ) diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 27b8eef7bbd6..36b6641d94a6 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -50,9 +50,9 @@ #include <basic/sbstar.hxx> #include <com/sun/star/container/XNameContainer.hpp> -#include <com/sun/star/script/XLibraryContainer.hpp> -#include <com/sun/star/script/XVBAModuleInfo.hpp> #include <com/sun/star/script/ModuleType.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/script/vba/XVBAModuleInfo.hpp> #include <list> @@ -2605,7 +2605,6 @@ uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, St script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule ) { - ::rtl::OUString sVbaOption( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" )); script::ModuleInfo sModuleInfo; sModuleInfo.ModuleType = script::ModuleType::DOCUMENT; sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule ); @@ -2648,7 +2647,7 @@ void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String if ( sTmpSource.getLength() == 0 ) sTmpSource = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" )); aSourceAny <<= sTmpSource; - uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); + uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); if ( xVBAModuleInfo.is() ) { String sCodeName( genModuleName ); @@ -2679,7 +2678,7 @@ void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ) } if( xLib.is() ) { - uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); + uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); if( xLib->hasByName( sModuleName ) ) xLib->removeByName( sModuleName ); if ( xVBAModuleInfo.is() ) diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index a446c86b4d1b..d5d7f6e09292 100755..100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -29,15 +29,11 @@ #include "precompiled_sc.hxx" // System - Includes ----------------------------------------------------- - - #include "scitems.hxx" #include <editeng/eeitem.hxx> #include <editeng/svxenum.hxx> #include <svx/algitem.hxx> - - #include <sot/clsids.hxx> #include <unotools/securityoptions.hxx> #include <tools/stream.hxx> @@ -68,11 +64,15 @@ #include "chgtrack.hxx" #include "chgviset.hxx" #include <sfx2/request.hxx> -#include <com/sun/star/document/UpdateDocMode.hpp> #include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/document/UpdateDocMode.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <com/sun/star/sheet/XSpreadsheetView.hpp> #include <com/sun/star/task/XJob.hpp> - +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> +#include <vbahelper/vbaaccesshelper.hxx> #include "scabstdlg.hxx" //CHINA001 #include <sot/formats.hxx> @@ -127,8 +127,9 @@ #include <rtl/logfile.hxx> #include <comphelper/processfactory.hxx> -#include <basic/sbstar.hxx> -#include <basic/basmgr.hxx> +#include "uiitems.hxx" +#include "cellsuno.hxx" + using namespace com::sun::star; using ::rtl::OUString; using ::rtl::OUStringBuffer; @@ -374,28 +375,7 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet) } else aDocument.SetInsertingFromOtherDoc( FALSE ); -#if 0 // disable load of vba related libraries - // add vba globals ( if they are availabl ) - uno::Any aGlobs; - uno::Sequence< uno::Any > aArgs(1); - aArgs[ 0 ] <<= GetModel(); - aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); - GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); - // Fake ThisComponent being setup by Activate ( which is a view - // related thing ), - // a) if another document is opened then in theory ThisComponent - // will be reset as before, - // b) when this document is 'really' Activated then ThisComponent - // again will be set as before - // The only wrinkle seems if this document is loaded 'InVisible' - // but.. I don't see that this is possible from the vba API - // I could be wrong though - // There may be implications setting the current component - // too early :-/ so I will just manually set the Basic Variables - BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); - if ( pAppMgr ) - pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); -#endif + aDocument.SetImportingXML( FALSE ); aDocument.EnableExecuteLink( true ); aDocument.EnableUndo( TRUE ); @@ -517,9 +497,70 @@ BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium ) return bRet; } - void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor(); + if ( xVbaEvents.is() ) try + { + using namespace ::com::sun::star::script::vba::VBAEventId; + if (rHint.ISA(ScTablesHint) ) + { + const ScTablesHint& rScHint = static_cast< const ScTablesHint& >( rHint ); + if (rScHint.GetId() == SC_TAB_INSERTED) + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[0] <<= rScHint.GetTab1(); + xVbaEvents->processVbaEvent( WORKBOOK_NEWSHEET, aArgs ); + } + } + else if ( rHint.ISA( SfxEventHint ) ) + { + ULONG nEventId = static_cast< const SfxEventHint& >( rHint ).GetEventId(); + switch ( nEventId ) + { + case SFX_EVENT_ACTIVATEDOC: + { + uno::Sequence< uno::Any > aArgs; + xVbaEvents->processVbaEvent( WORKBOOK_ACTIVATE, aArgs ); + } + break; + case SFX_EVENT_DEACTIVATEDOC: + { + uno::Sequence< uno::Any > aArgs; + xVbaEvents->processVbaEvent( WORKBOOK_DEACTIVATE, aArgs ); + } + break; + case SFX_EVENT_OPENDOC: + { + uno::Sequence< uno::Any > aArgs; + xVbaEvents->processVbaEvent( WORKBOOK_OPEN, aArgs ); + } + break; + case SFX_EVENT_SAVEDOCDONE: + case SFX_EVENT_SAVEASDOCDONE: + case SFX_EVENT_SAVETODOCDONE: + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= true; + xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs ); + } + break; + case SFX_EVENT_SAVEASDOCFAILED: + case SFX_EVENT_SAVEDOCFAILED: + case SFX_EVENT_SAVETODOCFAILED: + { + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= false; + xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs ); + } + break; + } + } + } + catch( uno::Exception& ) + { + } + if (rHint.ISA(SfxSimpleHint)) // ohne Parameter { ULONG nSlot = ((const SfxSimpleHint&)rHint).GetId(); @@ -578,6 +619,25 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) SetReadOnlyUI( sal_True ); } } + + // VBA specific initialization + if( aDocument.IsInVBAMode() ) try + { + uno::Reference< frame::XModel > xModel( GetModel(), uno::UNO_SET_THROW ); + + // create VBAGlobals object if not yet done (this also creates the "ThisExcelDoc" symbol) + uno::Reference< lang::XMultiServiceFactory > xFactory( xModel, uno::UNO_QUERY_THROW ); + xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) ); + + // create the VBA document event processor + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= xModel; + xVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( this, "com.sun.star.script.vba.VBASpreadsheetEventProcessor" , aArgs ), uno::UNO_QUERY ); + aDocument.SetVbaEventProcessor( xVbaEvents ); + } + catch( uno::Exception& ) + { + } } break; case SFX_EVENT_VIEWCREATED: @@ -2252,6 +2312,45 @@ BOOL __EXPORT ScDocShell::DoSaveCompleted( SfxMedium * pNewStor ) } +sal_Bool ScDocShell::QuerySlotExecutable( USHORT nSlotId ) +{ + // #i112634# ask VBA event handlers whether to save or print the document + + using namespace ::com::sun::star::script::vba; + + sal_Int32 nVbaEventId = VBAEventId::NO_EVENT; + uno::Sequence< uno::Any > aArgs; + switch( nSlotId ) + { + case SID_SAVEDOC: + case SID_SAVEASDOC: + nVbaEventId = VBAEventId::WORKBOOK_BEFORESAVE; + aArgs.realloc( 1 ); + aArgs[ 0 ] <<= (nSlotId == SID_SAVEASDOC); + break; + case SID_PRINTDOC: + case SID_PRINTDOCDIRECT: + nVbaEventId = VBAEventId::WORKBOOK_BEFOREPRINT; + break; + } + + sal_Bool bSlotExecutable = sal_True; + if( nVbaEventId != VBAEventId::NO_EVENT ) try + { + uno::Reference< XVBAEventProcessor > xEventProcessor( aDocument.GetVbaEventProcessor(), uno::UNO_QUERY_THROW ); + xEventProcessor->processVbaEvent( nVbaEventId, aArgs ); + } + catch( util::VetoException& ) + { + bSlotExecutable = sal_False; + } + catch( uno::Exception& ) + { + } + return bSlotExecutable; +} + + USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing ) { if(SC_MOD()->GetCurRefDlgId()>0) @@ -2278,6 +2377,26 @@ USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing ) DoEnterHandler(); + // start 'Workbook_BeforeClose' VBA event handler for possible veto + if( !IsInPrepareClose() ) + { + try + { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( aDocument.GetVbaEventProcessor(), uno::UNO_SET_THROW ); + uno::Sequence< uno::Any > aArgs; + xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKBOOK_BEFORECLOSE, aArgs ); + } + catch( util::VetoException& ) + { + // if event processor throws VetoException, macro has vetoed close + return sal_False; + } + catch( uno::Exception& ) + { + } + } + // end handler code + USHORT nRet = SfxObjectShell::PrepareClose( bUI, bForBrowsing ); if (nRet == TRUE) // TRUE = schliessen aDocument.DisableIdle(TRUE); // nicht mehr drin rumpfuschen !!! diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 0993d2ce4a14..d50ce6f21c9c 100755..100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -1293,7 +1293,7 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) // (might check for the presence of any formulas on each sheet) SCTAB nTabCount = aDocument.GetTableCount(); SCTAB nTab; - if (aDocument.HasSheetEventScript( SC_SHEETEVENT_CALCULATE )) + if (aDocument.HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true )) // search also for VBA hendler for (nTab=0; nTab<nTabCount; nTab++) aDocument.SetCalcNotification(nTab); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index 5b4fc6227225..19147cfaf61f 100755..100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -215,6 +215,7 @@ public: virtual BOOL SaveCompleted( const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& ); // SfxInPlaceObject virtual BOOL DoSaveCompleted( SfxMedium * pNewStor); // SfxObjectShell + virtual sal_Bool QuerySlotExecutable( USHORT nSlotId ); virtual void Draw( OutputDevice *, const JobSetup & rSetup, USHORT nAspect = ASPECT_CONTENT ); diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx index 2d8340ad030b..70845f6c0bc9 100644 --- a/sc/source/ui/undo/undotab.cxx +++ b/sc/source/ui/undo/undotab.cxx @@ -28,18 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - -//------------------------------------------------------------------ - -// ?#define _MACRODLG_HXX -// ? #define _BIGINT_HXX -// ? #define _SVDXOUT_HXX -// ? #define _SVDATTR_HXX -// ? #define _SVDSURO_HXX - -// INCLUDE --------------------------------------------------------------- - #include <sfx2/app.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 6d267d4098ff..3d3f0f479601 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -28,14 +28,13 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - #include "scitems.hxx" #include <svx/fmdpage.hxx> #include <svx/fmview.hxx> #include <svx/svditer.hxx> #include <svx/svdpage.hxx> #include <svx/svxids.hrc> +#include <svx/unoshape.hxx> #include <svl/numuno.hxx> #include <svl/smplhint.hxx> @@ -49,6 +48,7 @@ #include <tools/multisel.hxx> #include <tools/resary.hxx> #include <toolkit/awt/vclxdevice.hxx> + #include <ctype.h> #include <float.h> // DBL_MAX @@ -61,6 +61,7 @@ #include <com/sun/star/lang/ServiceNotRegisteredException.hpp> #include <com/sun/star/document/XDocumentEventBroadcaster.hpp> #include <com/sun/star/script/XInvocation.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <com/sun/star/reflection/XIdlClassProvider.hpp> #include <comphelper/processfactory.hxx> @@ -100,10 +101,6 @@ #include "sc.hrc" #include "scresid.hxx" -#ifndef _SVX_UNOSHAPE_HXX -#include <svx/unoshape.hxx> -#endif - using namespace com::sun::star; //------------------------------------------------------------------------ @@ -592,8 +589,8 @@ void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) DELETEZ( pPrintFuncCache ); - // handle "OnCalculate" sheet events - if ( pDocShell && pDocShell->GetDocument()->HasSheetEventScript( SC_SHEETEVENT_CALCULATE ) ) + // handle "OnCalculate" sheet events (search also for VBA event handlers) + if ( pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript( SC_SHEETEVENT_CALCULATE, true ) ) HandleCalculateEvents(); } } @@ -2156,20 +2153,8 @@ bool ScModelObj::HasChangesListeners() const if ( maChangesListeners.getLength() > 0 ) return true; - if ( pDocShell ) - { - // "change" event set in any sheet? - ScDocument* pDoc = pDocShell->GetDocument(); - SCTAB nTabCount = pDoc->GetTableCount(); - for (SCTAB nTab = 0; nTab < nTabCount; nTab++) - { - const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); - if (pEvents && pEvents->GetScript(SC_SHEETEVENT_CHANGE)) - return true; - } - } - - return false; + // "change" event set in any sheet? + return pDocShell && pDocShell->GetDocument()->HasAnySheetEventScript(SC_SHEETEVENT_CHANGE); } void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges, @@ -2283,17 +2268,29 @@ void ScModelObj::HandleCalculateEvents() SCTAB nTabCount = pDoc->GetTableCount(); for (SCTAB nTab = 0; nTab < nTabCount; nTab++) { - const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); - if (pEvents) + if (pDoc->HasCalcNotification(nTab)) { - const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE); - if (pScript && pDoc->HasCalcNotification(nTab)) + if (const ScSheetEvents* pEvents = pDoc->GetSheetEvents( nTab )) + { + if (const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE)) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + + try + { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW ); + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= nTab; + xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_CALCULATE ), aArgs ); + } + catch( uno::Exception& ) { - uno::Any aRet; - uno::Sequence<uno::Any> aParams; - uno::Sequence<sal_Int16> aOutArgsIndex; - uno::Sequence<uno::Any> aOutArgs; - pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); } } } diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx index 0b3a6f01f9ea..a173e6d1e051 100644 --- a/sc/source/ui/unoobj/servuno.cxx +++ b/sc/source/ui/unoobj/servuno.cxx @@ -65,6 +65,7 @@ #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/form/XFormsSupplier.hpp> #include <svx/unomod.hxx> +#include <vbahelper/vbaaccesshelper.hxx> #include <comphelper/processfactory.hxx> #include <basic/basmgr.hxx> @@ -72,19 +73,6 @@ using namespace ::com::sun::star; -#ifndef CWS_NPOWER14MISCFIXES -uno::Reference< uno::XInterface > lcl_createVBAUnoAPIServiceWithArgs( SfxObjectShell* pShell, const sal_Char* _pAsciiName, const uno::Sequence< uno::Any >& aArgs ) throw (uno::RuntimeException) -{ - uno::Any aUnoVar; - if ( !pShell || !pShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aUnoVar ) ) - throw lang::IllegalArgumentException(); - uno::Reference< lang::XMultiServiceFactory > xVBAFactory( aUnoVar, uno::UNO_QUERY_THROW ); - ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) ); - uno::Reference< uno::XInterface > xIf = xVBAFactory->createInstanceWithArguments( sVarName, aArgs ); - return xIf; -} -#endif - class ScVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper1< container::XNameAccess > { uno::Any maWorkbook; @@ -98,13 +86,10 @@ public: throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("")), uno::Reference< uno::XInterface >() ); uno::Sequence< uno::Any > aArgs(2); - aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() ); + // access the application object ( parent for workbook ) + aArgs[0] = uno::Any( ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.Application", uno::Sequence< uno::Any >() ) ); aArgs[1] = uno::Any( mpDocShell->GetModel() ); -#ifdef CWS_NPOWER14MISCFIXES maWorkbook <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs ); -#else - maWorkbook <<= lcl_createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs ); -#endif } virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException ) @@ -139,13 +124,8 @@ public: aArgs[0] = maWorkbook; aArgs[1] = uno::Any( xModel ); aArgs[2] = uno::Any( rtl::OUString( sSheetName ) ); -#ifdef CWS_NPOWER14MISCFIXES // use the convience function maCachedObject <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs ); -#else - // use the temp function - maCachedObject <<= lcl_createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs ); -#endif break; } } @@ -557,6 +537,7 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( break; case SC_SERVICE_OPCODEMAPPER: + if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); ScAddress aAddress; @@ -566,44 +547,35 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( break; } case SC_SERVICE_VBAOBJECTPROVIDER: - if ( pDocShell ) + if (pDocShell && pDocShell->GetDocument()->IsInVBAMode()) { OSL_TRACE("**** creating VBA Object mapper"); xRet.set(static_cast<container::XNameAccess*>(new ScVbaObjectForCodeNameProvider( pDocShell ))); } break; case SC_SERVICE_VBACODENAMEPROVIDER: + if (pDocShell && pDocShell->GetDocument()->IsInVBAMode()) { - // Only create the excel faking service for excel docs - const SfxFilter *pFilt = pDocShell->GetMedium()->GetFilter(); - if ( pFilt && pFilt->IsAlienFormat() ) - { - // application/vnd.ms-excel is the mime type for Excel - static const rtl::OUString sExcelMimeType( RTL_CONSTASCII_USTRINGPARAM( "application/vnd.ms-excel" ) ); - if ( sExcelMimeType.equals( pFilt->GetMimeType() ) ) - xRet.set(static_cast<document::XCodeNameQuery*>(new ScVbaCodeNameProvider( pDocShell ))); - } - break; + OSL_TRACE("**** creating VBA Object provider"); + xRet.set(static_cast<document::XCodeNameQuery*>(new ScVbaCodeNameProvider( pDocShell ))); } + break; case SC_SERVICE_VBAGLOBALS: + if (pDocShell) { uno::Any aGlobs; - ScDocument* pDoc = pDocShell->GetDocument(); - if ( pDoc ) + if ( !pDocShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aGlobs ) ) { - if ( !pDocShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aGlobs ) ) - { - uno::Sequence< uno::Any > aArgs(1); - aArgs[ 0 ] <<= pDocShell->GetModel(); - aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); - pDocShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); - BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); - if ( pAppMgr ) - pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); - } - aGlobs >>= xRet; + uno::Sequence< uno::Any > aArgs(1); + aArgs[ 0 ] <<= pDocShell->GetModel(); + xRet = ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); + pDocShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", uno::Any( xRet ) ); + BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); + if ( pAppMgr ) + pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); } } + break; } return xRet; diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index d10d3ba54f86..fd1e655b8ffb 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -28,6 +28,10 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> +#include <com/sun/star/view/DocumentZoomType.hpp> #include <editeng/outliner.hxx> #include <svx/fmdpage.hxx> @@ -67,8 +71,6 @@ #include "appoptio.hxx" #include "gridwin.hxx" #include "sheetevents.hxx" -#include <com/sun/star/view/DocumentZoomType.hpp> -#include <com/sun/star/awt/MouseButton.hpp> #include "AccessibilityHints.hxx" #include <svx/sdrhittesthelper.hxx> @@ -468,7 +470,8 @@ void SAL_CALL ScViewPaneObj::release() throw() //UNUSED2008-05 aPropSet( lcl_GetViewOptPropertyMap() ), //UNUSED2008-05 aMouseClickHandlers( 0 ), //UNUSED2008-05 aActivationListeners( 0 ), -//UNUSED2008-05 bDrawSelModeSet(sal_False) +//UNUSED2008-05 bDrawSelModeSet(sal_False), +//UNUSED2008-05 bFilteredRangeSelection(sal_True) //UNUSED2008-05 { //UNUSED2008-05 } @@ -551,10 +554,22 @@ void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, sal_Int32 nEvent ) uno::Sequence<uno::Any> aParams; uno::Sequence<sal_Int16> aOutArgsIndex; uno::Sequence<uno::Any> aOutArgs; - /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); } } + + // execute VBA event handlers + try + { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW ); + // the parameter is the clicked object, as in the mousePressed call above + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= nTab; + xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ); + } + catch( uno::Exception& ) + { + } } void ScTabViewObj::SheetChanged() @@ -1242,14 +1257,12 @@ bool ScTabViewObj::IsMouseListening() const return true; // also include sheet events, because MousePressed must be called for them - ScTabViewShell* pViewSh = GetViewShell(); - ScViewData* pViewData = pViewSh->GetViewData(); - const ScSheetEvents* pEvents = pViewData->GetDocument()->GetSheetEvents(pViewData->GetTabNo()); - if ( pEvents && ( pEvents->GetScript(SC_SHEETEVENT_RIGHTCLICK) != NULL || - pEvents->GetScript(SC_SHEETEVENT_DOUBLECLICK) != NULL ) ) - return true; - - return false; + ScViewData* pViewData = GetViewShell()->GetViewData(); + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + return + pDoc->HasSheetEventScript( nTab, SC_SHEETEVENT_RIGHTCLICK, true ) || + pDoc->HasSheetEventScript( nTab, SC_SHEETEVENT_DOUBLECLICK, true ); } sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) @@ -1257,33 +1270,29 @@ sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) { sal_Bool bReturn(sal_False); - if (aMouseClickHandlers.Count()) + uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y)); + if (aMouseClickHandlers.Count() && xTarget.is()) { - uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y)); + awt::EnhancedMouseEvent aMouseEvent; - if (xTarget.is()) - { - awt::EnhancedMouseEvent aMouseEvent; + aMouseEvent.Buttons = e.Buttons; + aMouseEvent.X = e.X; + aMouseEvent.Y = e.Y; + aMouseEvent.ClickCount = e.ClickCount; + aMouseEvent.PopupTrigger = e.PopupTrigger; + aMouseEvent.Target = xTarget; - aMouseEvent.Buttons = e.Buttons; - aMouseEvent.X = e.X; - aMouseEvent.Y = e.Y; - aMouseEvent.ClickCount = e.ClickCount; - aMouseEvent.PopupTrigger = e.PopupTrigger; - aMouseEvent.Target = xTarget; - - for ( USHORT n=0; n<aMouseClickHandlers.Count(); n++ ) + for ( USHORT n=0; n<aMouseClickHandlers.Count(); n++ ) + { + try { - try - { - if (!(*aMouseClickHandlers[n])->mousePressed( aMouseEvent )) - bReturn = sal_True; - } - catch ( uno::Exception& ) - { - aMouseClickHandlers.DeleteAndDestroy(n); - --n; // because it will be increased again in the loop - } + if (!(*aMouseClickHandlers[n])->mousePressed( aMouseEvent )) + bReturn = sal_True; + } + catch ( uno::Exception& ) + { + aMouseClickHandlers.DeleteAndDestroy(n); + --n; // because it will be increased again in the loop } } } @@ -1291,7 +1300,7 @@ sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) // handle sheet events bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 ); bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 ); - if ( ( bDoubleClick || bRightClick ) && !bReturn ) + if ( ( bDoubleClick || bRightClick ) && !bReturn && xTarget.is()) { sal_Int32 nEvent = bDoubleClick ? SC_SHEETEVENT_DOUBLECLICK : SC_SHEETEVENT_RIGHTCLICK; @@ -1307,28 +1316,41 @@ sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) if (pScript) { // the macro parameter is the clicked object, as in the mousePressed call above - uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y)); - if (xTarget.is()) - { - uno::Sequence<uno::Any> aParams(1); - aParams[0] <<= xTarget; + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; - uno::Any aRet; - uno::Sequence<sal_Int16> aOutArgsIndex; - uno::Sequence<uno::Any> aOutArgs; + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; - /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); - // look for a boolean return value of true - sal_Bool bRetValue = sal_False; - if (aRet >>= bRetValue) - { - if (bRetValue) - bReturn = sal_True; - } + // look for a boolean return value of true + sal_Bool bRetValue = sal_False; + if (aRet >>= bRetValue) + { + if (bRetValue) + bReturn = sal_True; } } } + + // execute VBA event handler + if (!bReturn && xTarget.is()) try + { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW ); + // the parameter is the clicked object, as in the mousePressed call above + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= xTarget; + xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ); + } + catch( util::VetoException& ) + { + bReturn = sal_True; + } + catch( uno::Exception& ) + { + } } return bReturn; @@ -1820,14 +1842,25 @@ void ScTabViewObj::SelectionChanged() // the macro parameter is the selection as returned by getSelection uno::Sequence<uno::Any> aParams(1); aParams[0] = getSelection(); - uno::Any aRet; uno::Sequence<sal_Int16> aOutArgsIndex; uno::Sequence<uno::Any> aOutArgs; - /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); } } + + // execute VBA event handler + try + { + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( pDoc->GetVbaEventProcessor(), uno::UNO_SET_THROW ); + // the parameter is the clicked object, as in the mousePressed call above + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= getSelection(); + xVbaEvents->processVbaEvent( ScSheetEvents::GetVbaSheetEventId( SC_SHEETEVENT_SELECT ), aArgs ); + } + catch( uno::Exception& ) + { + } } diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index b1c4db637434..2c39d7154b4b 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -31,6 +31,7 @@ #include "scmod.hxx" #include "cellsuno.hxx" #include <comphelper/processfactory.hxx> +#include <com/sun/star/sheet/XSheetCellRange.hpp> using namespace ::com::sun::star; using namespace ::ooo::vba; @@ -41,6 +42,27 @@ namespace vba { namespace excel { + +ScDocShell* GetDocShellFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) +{ + ScCellRangesBase* pScCellRangesBase = ScCellRangesBase::getImplementation( xRange ); + if ( !pScCellRangesBase ) + { + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying doc shell uno range object" ) ), uno::Reference< uno::XInterface >() ); + } + return pScCellRangesBase->GetDocShell(); +} + +ScDocument* GetDocumentFromRange( const uno::Reference< uno::XInterface >& xRange ) throw ( uno::RuntimeException ) +{ + ScDocShell* pDocShell = GetDocShellFromRange( xRange ); + if ( !pDocShell ) + { + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying document from uno range object" ) ), uno::Reference< uno::XInterface >() ); + } + return pDocShell->GetDocument(); +} + void implSetZoom( const uno::Reference< frame::XModel >& xModel, sal_Int16 nZoom, std::vector< SCTAB >& nTabs ) { ScTabViewShell* pViewSh = excel::getBestViewShell( xModel ); @@ -207,12 +229,40 @@ getViewFrame( const uno::Reference< frame::XModel >& xModel ) return NULL; } +uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) +{ + uno::Reference< sheet::XSheetCellRange > xSheetRange( xRange, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xProps( xSheetRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + rtl::OUString sCodeName; + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) ) >>= sCodeName; + // #TODO #FIXME ideally we should 'throw' here if we don't get a valid parent, but... it is possible + // to create a module ( and use 'Option VBASupport 1' ) for a calc document, in this scenario there + // are *NO* special document module objects ( of course being able to switch between vba/non vba mode at + // the document in the future could fix this, especially IF the switching of the vba mode takes care to + // create the special document module objects if they don't exist. + uno::Reference< XHelperInterface > xParent( ov::getUnoDocModule( sCodeName, GetDocShellFromRange( xRange ) ), uno::UNO_QUERY ); + + return xParent; +} + +uno::Reference< XHelperInterface > +getUnoSheetModuleObj( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) +{ + uno::Reference< container::XEnumerationAccess > xEnumAccess( xRanges, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xEnum = xEnumAccess->createEnumeration(); + uno::Reference< table::XCellRange > xRange( xEnum->nextElement(), uno::UNO_QUERY_THROW ); + + return getUnoSheetModuleObj( xRange ); +} + SfxItemSet* ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj ) { return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0; } + } //excel } //vba } //ooo diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx index 9af804ab169f..da0474e6ceb0 100644 --- a/sc/source/ui/vba/excelvbahelper.hxx +++ b/sc/source/ui/vba/excelvbahelper.hxx @@ -29,6 +29,9 @@ #include<vbahelper/vbahelper.hxx> #include <docsh.hxx> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> +#include <ooo/vba/XHelperInterface.hpp> class ScCellRangesBase; @@ -48,6 +51,11 @@ namespace ooo ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext ); SfxViewFrame* getViewFrame( const css::uno::Reference< css::frame::XModel >& xModel ); + css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges ) throw ( css::uno::RuntimeException ); + css::uno::Reference< ooo::vba::XHelperInterface > getUnoSheetModuleObj( const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::uno::RuntimeException ); + ScDocShell* GetDocShellFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); + ScDocument* GetDocumentFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); + css::uno::Reference< css::frame::XModel > GetModelFromRange( const css::uno::Reference< css::uno::XInterface >& xRange ) throw ( css::uno::RuntimeException ); class ScVbaCellRangeAccess { public: diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk index 0a84b8dd12a5..4cb7e3eb064b 100644 --- a/sc/source/ui/vba/makefile.mk +++ b/sc/source/ui/vba/makefile.mk @@ -102,7 +102,9 @@ SLOFILES= \ $(SLO)$/vbapagesetup.obj \ $(SLO)$/vbapagebreak.obj \ $(SLO)$/vbapagebreaks.obj \ + $(SLO)$/vbaeventshelper.obj \ $(SLO)$/service.obj + .ENDIF # --- Targets ------------------------------------------------------ diff --git a/sc/source/ui/vba/service.cxx b/sc/source/ui/vba/service.cxx index 8be0f6d9f726..2b1f14cf154a 100644 --- a/sc/source/ui/vba/service.cxx +++ b/sc/source/ui/vba/service.cxx @@ -66,6 +66,10 @@ namespace application { extern sdecl::ServiceDecl const serviceDecl; } +namespace vbaeventshelper +{ +extern sdecl::ServiceDecl const serviceDecl; +} namespace textframe { extern sdecl::ServiceDecl const serviceDecl; @@ -87,7 +91,7 @@ extern "C" #if 0 // Component registration if ( component_writeInfoHelper( pServiceManager, pRegistryKey, - range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) ) + range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl ) ) { // Singleton registration try @@ -110,7 +114,7 @@ extern "C" #else // Component registration return component_writeInfoHelper( pServiceManager, pRegistryKey, - range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, textframe::serviceDecl ); + range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ) && component_writeInfoHelper( pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl, textframe::serviceDecl ); #endif } @@ -122,8 +126,8 @@ extern "C" OSL_TRACE("In component_getFactory for %s", pImplName ); void* pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, range::serviceDecl, workbook::serviceDecl, worksheet::serviceDecl, globals::serviceDecl, window::serviceDecl, hyperlink::serviceDecl, application::serviceDecl ); - if( !pRet ) - pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, textframe::serviceDecl ); + if( !pRet ) + pRet = component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey, vbaeventshelper::serviceDecl, textframe::serviceDecl ); OSL_TRACE("Ret is 0x%x", pRet); return pRet; } diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index aea8d8bc11d4..8f5aba5c4acb 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -24,14 +24,14 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <stdio.h> +#include <stdio.h> -#include<com/sun/star/sheet/XSpreadsheetView.hpp> +#include <com/sun/star/sheet/XSpreadsheetView.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> -#include<com/sun/star/view/XSelectionSupplier.hpp> +#include <com/sun/star/view/XSelectionSupplier.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> -#include<ooo/vba/excel/XlCalculation.hpp> +#include <ooo/vba/excel/XlCalculation.hpp> #include <com/sun/star/sheet/XCellRangeReferrer.hpp> #include <com/sun/star/sheet/XCalculatable.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> @@ -117,7 +117,8 @@ public: ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) : ScVbaApplication_BASE( xContext ), m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), - m_xDisplayAlerts( sal_True) + m_bDisplayAlerts( sal_True ), + m_bEnableEvents( sal_True ) { } @@ -193,18 +194,47 @@ ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeE uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { - return new ActiveWorkbook( this, mxContext ); + uno::Reference< excel::XWorkbook > xWrkbk; + ScDocShell* pShell = excel::getDocShell( getCurrentExcelDoc( mxContext ) ); + if ( pShell ) + { + String aName; + if ( pShell->GetDocument() ) + { + aName = pShell->GetDocument()->GetCodeName(); + xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY ); + // fallback ( e.g. it's possible a new document was created via the api ) + // in that case the document will not have the appropriate Document Modules + // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document + // vba mode etc. ) + if ( !xWrkbk.is() ) + return new ActiveWorkbook( this, mxContext ); + } + } + return xWrkbk; } uno::Reference< excel::XWorkbook > SAL_CALL ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException) { - uno::Reference< frame::XModel > xModel = getThisExcelDoc(mxContext); - if( !xModel.is() ) - return uno::Reference< excel::XWorkbook >(); - - ScVbaWorkbook *pWb = new ScVbaWorkbook( this, mxContext, xModel ); - return uno::Reference< excel::XWorkbook > (pWb); + uno::Reference< excel::XWorkbook > xWrkbk; + ScDocShell* pShell = excel::getDocShell( getThisExcelDoc( mxContext ) ); + if ( pShell ) + { + String aName; + if ( pShell->GetDocument() ) + { + aName = pShell->GetDocument()->GetCodeName(); + xWrkbk.set( getUnoDocModule( aName, pShell ), uno::UNO_QUERY ); + // fallback ( e.g. it's possible a new document was created via the api ) + // in that case the document will not have the appropriate Document Modules + // #TODO #FIXME ( needs to be fixes as part of providing support for an overall document + // vba mode etc. ) + if ( !xWrkbk.is() ) + return new ActiveWorkbook( this, mxContext ); + } + } + return xWrkbk; } uno::Reference< XAssistant > SAL_CALL @@ -246,10 +276,10 @@ ScVbaApplication::getSelection() throw (uno::RuntimeException) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( getCurrentDocument()->getCurrentSelection(), ::uno::UNO_QUERY); if ( xRanges.is() ) - return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( this, mxContext, xRanges ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ) ) ); } - return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( this, mxContext, xRange ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >(new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ) ) ); } else { @@ -531,10 +561,8 @@ ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) thro ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); try { - // FIXME: pass proper Worksheet parent uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( - uno::Reference< XHelperInterface >(), mxContext, sRangeName, - excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); if( bScroll ) { @@ -681,14 +709,27 @@ ScVbaApplication::getName() throw (uno::RuntimeException) void SAL_CALL ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { - m_xDisplayAlerts = displayAlerts; + m_bDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { - return m_xDisplayAlerts; + return m_bDisplayAlerts; +} + +void SAL_CALL +ScVbaApplication::setEnableEvents(sal_Bool bEnable) throw (uno::RuntimeException) +{ + m_bEnableEvents = bEnable; } + +sal_Bool SAL_CALL +ScVbaApplication::getEnableEvents() throw (uno::RuntimeException) +{ + return m_bEnableEvents; +} + void SAL_CALL ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException ) { @@ -1068,12 +1109,13 @@ ScVbaApplication::Intersect( const uno::Reference< excel::XRange >& Arg1, const ScDocShell* pDocShell = excel::getDocShell( xModel ); if ( aCellRanges.Count() == 1 ) { - xRefRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, new ScCellRangeObj( pDocShell, *aCellRanges.First() ) ); + uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() )); + xRefRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), mxContext, xRange ); } else if ( aCellRanges.Count() > 1 ) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) ); - xRefRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRanges ); + xRefRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ) , mxContext, xRanges ); } return xRefRange; @@ -1158,12 +1200,13 @@ ScVbaApplication::Union( const uno::Reference< excel::XRange >& Arg1, const uno: if ( aCellRanges.Count() == 1 ) { // normal range - xRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, new ScCellRangeObj( pDocShell, *aCellRanges.First() ) ); + uno::Reference< table::XCellRange > xCalcRange( new ScCellRangeObj( pDocShell, *aCellRanges.First() ) ); + xRange = new ScVbaRange( excel::getUnoSheetModuleObj( xCalcRange ), mxContext, xCalcRange ); } else if ( aCellRanges.Count() > 1 ) // Multi-Area { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocShell, aCellRanges ) ); - xRange = new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRanges ); + xRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRanges ), mxContext, xRanges ); } // #FIXME need proper (WorkSheet) parent diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index 96638651bcd1..a7be5feb1d27 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -43,7 +43,9 @@ class ScVbaApplication : public ScVbaApplication_BASE { private: sal_Int32 m_xCalculation; - sal_Bool m_xDisplayAlerts; + sal_Bool m_bDisplayAlerts; + sal_Bool m_bEnableEvents; + rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException ); protected: @@ -100,6 +102,9 @@ public: virtual ::sal_Int32 SAL_CALL getCursor() throw (css::uno::RuntimeException); virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getEnableEvents() throw (css::uno::RuntimeException); + virtual void SAL_CALL setEnableEvents( sal_Bool bEnable ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL wait( double time ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbachartobjects.cxx b/sc/source/ui/vba/vbachartobjects.cxx index 41b26501f4ad..5117cfd75858 100644 --- a/sc/source/ui/vba/vbachartobjects.cxx +++ b/sc/source/ui/vba/vbachartobjects.cxx @@ -47,16 +47,15 @@ using namespace ::ooo::vba; class ChartObjectEnumerationImpl : public EnumerationHelperImpl { uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier; - uno::Reference< XHelperInterface > xParent; public: - ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ), xParent( _xParent ) {} + ChartObjectEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< drawing::XDrawPageSupplier >& _xDrawPageSupplier, const uno::Reference< XHelperInterface >& _xParent ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( _xParent, xContext, xEnumeration ), xDrawPageSupplier( _xDrawPageSupplier ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< table::XTableChart > xTableChart( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); // parent Object is sheet - return uno::makeAny( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) ); + return uno::makeAny( uno::Reference< excel::XChartObject > ( new ScVbaChartObject( m_xParent, m_xContext, xTableChart, xDrawPageSupplier ) ) ); } }; diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx index a68dd4245741..7a6d3d774937 100644 --- a/sc/source/ui/vba/vbacomments.cxx +++ b/sc/source/ui/vba/vbacomments.cxx @@ -50,10 +50,11 @@ class CommentEnumeration : public EnumerationHelperImpl css::uno::Reference< css::frame::XModel > mxModel; public: CommentEnumeration( + const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : - EnumerationHelperImpl( xContext, xEnumeration ), + EnumerationHelperImpl( xParent, xContext, xEnumeration ), mxModel( xModel, uno::UNO_SET_THROW ) {} @@ -80,8 +81,7 @@ uno::Reference< container::XEnumeration > ScVbaComments::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - - return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration(), mxModel ); + return new CommentEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration(), mxModel ); } uno::Any diff --git a/sc/source/ui/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx new file mode 100755 index 000000000000..45667adf2f2c --- /dev/null +++ b/sc/source/ui/vba/vbaeventshelper.cxx @@ -0,0 +1,753 @@ +/************************************************************************* + * + * 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 "vbaeventshelper.hxx" + +#include <com/sun/star/awt/XWindowListener.hpp> +#include <com/sun/star/frame/XBorderResizeListener.hpp> +#include <com/sun/star/frame/XControllerBorder.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/util/XChangesListener.hpp> +#include <com/sun/star/util/XChangesNotifier.hpp> +#include <com/sun/star/util/XCloseListener.hpp> + +#include <ooo/vba/excel/XApplication.hpp> + +#include <cppuhelper/implbase4.hxx> +#include <toolkit/unohlp.hxx> +#include <vbahelper/helperdecl.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> + +#include "cellsuno.hxx" +#include "convuno.hxx" + +using namespace ::com::sun::star; +using namespace ::com::sun::star::script::vba::VBAEventId; +using namespace ::ooo::vba; + +// ============================================================================ + +typedef ::cppu::WeakImplHelper4< + awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE; + +// This class is to process Workbook window related event +class ScVbaEventsListener : public ScVbaEventsListener_BASE +{ +public : + ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ); + virtual ~ScVbaEventsListener(); + + void startListening(); + void stopListening(); + + // XWindowListener + virtual void SAL_CALL windowResized( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowMoved( const awt::WindowEvent& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowShown( const lang::EventObject& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL windowHidden( const lang::EventObject& aEvent ) throw (uno::RuntimeException); + virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw (uno::RuntimeException); + + // XCloseListener + virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership ) throw (util::CloseVetoException, uno::RuntimeException); + virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException); + + // XBorderResizeListener + virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& aObject, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException); + + // XChangesListener + virtual void SAL_CALL changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException); + +private: + uno::Reference< frame::XFrame > getFrame(); + uno::Reference< awt::XWindow > getContainerWindow(); + bool isMouseReleased(); + DECL_LINK( fireResizeMacro, void* ); + void processWindowResizeMacro(); + +private: + ::osl::Mutex maMutex; + ScVbaEventsHelper& mrVbaEvents; + uno::Reference< frame::XModel > mxModel; + ScDocShell* mpDocShell; + bool mbWindowResized; + bool mbBorderChanged; + bool mbDisposed; +}; + +// ---------------------------------------------------------------------------- + +ScVbaEventsListener::ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) : + mrVbaEvents( rVbaEvents ), + mxModel( rxModel ), + mpDocShell( pDocShell ), + mbWindowResized( false ), + mbBorderChanged( false ), + mbDisposed( !rxModel.is() ) +{ + OSL_TRACE( "ScVbaEventsListener::ScVbaEventsListener( 0x%x ) - ctor ", this ); +} + +ScVbaEventsListener::~ScVbaEventsListener() +{ + OSL_TRACE( "ScVbaEventsListener::~ScVbaEventsListener( 0x%x ) - dtor ", this ); + stopListening(); +} + +void ScVbaEventsListener::startListening() +{ + if( !mbDisposed ) + { + // add window listener + try + { + uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW ); + xWindow->addWindowListener( this ); + } + catch( uno::Exception& ) + { + } + // add close listener + try + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW ); + xCloseBroadcaster->addCloseListener( this ); + } + catch( uno::Exception& ) + { + } + // add Border resize listener + try + { + uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xControllerBorder->addBorderResizeListener( this ); + } + catch( uno::Exception& ) + { + } + // add content change listener + try + { + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->addChangesListener( this ); + } + catch( uno::Exception& ) + { + } + } +} + +void ScVbaEventsListener::stopListening() +{ + if( !mbDisposed ) + { + try + { + uno::Reference< awt::XWindow > xWindow( getContainerWindow(), uno::UNO_QUERY_THROW ); + xWindow->removeWindowListener( this ); + } + catch( uno::Exception& ) + { + } + try + { + uno::Reference< util::XCloseBroadcaster > xCloseBroadcaster( mxModel, uno::UNO_QUERY_THROW ); + xCloseBroadcaster->removeCloseListener( this ); + } + catch( uno::Exception& ) + { + } + try + { + uno::Reference< frame::XControllerBorder > xControllerBorder( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + xControllerBorder->removeBorderResizeListener( this ); + } + catch( uno::Exception& ) + { + } + try + { + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->removeChangesListener( this ); + } + catch( uno::Exception& ) + { + } + } + mbDisposed = true; +} + +void SAL_CALL ScVbaEventsListener::windowResized( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + // Workbook_window_resize event + mbWindowResized = true; + if( !mbDisposed && mbBorderChanged ) + { + if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) ) + { + mbBorderChanged = mbWindowResized = false; + acquire(); // ensure we don't get deleted before the event is handled + Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); + } + } +} + +void SAL_CALL ScVbaEventsListener::windowMoved( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + // not interest this time +} + +void SAL_CALL ScVbaEventsListener::windowShown( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + // not interest this time +} + +void SAL_CALL ScVbaEventsListener::windowHidden( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + // not interest this time +} + +void SAL_CALL ScVbaEventsListener::disposing( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +{ + ::osl::MutexGuard aGuard( maMutex ); + OSL_TRACE( "ScVbaEventsListener::disposing( 0x%x )", this ); + mbDisposed = true; +} + +void SAL_CALL ScVbaEventsListener::queryClosing( const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) throw (util::CloseVetoException, uno::RuntimeException) +{ + // it can cancel the close, but need to throw a CloseVetoException, and it will be transmit to caller. +} + +void SAL_CALL ScVbaEventsListener::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + stopListening(); +} + +void SAL_CALL ScVbaEventsListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& /*aObject*/, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException) +{ + ::osl::MutexGuard aGuard( maMutex ); + // work with WindowResized event to guard Window Resize event. + mbBorderChanged = true; + if( !mbDisposed && mbWindowResized ) + { + if( /*Window* pWindow =*/ VCLUnoHelper::GetWindow( getContainerWindow() ) ) + { + mbWindowResized = mbBorderChanged = false; + acquire(); // ensure we don't get deleted before the timer fires. + Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); + } + } +} + +void SAL_CALL ScVbaEventsListener::changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException) +{ + sal_Int32 nCount = aEvent.Changes.getLength(); + if( nCount == 0 ) + return; + + util::ElementChange aChange = aEvent.Changes[ 0 ]; + rtl::OUString sOperation; + aChange.Accessor >>= sOperation; + if( !sOperation.equalsIgnoreAsciiCaseAscii("cell-change") ) + return; + + if( nCount == 1 ) + { + uno::Reference< table::XCellRange > xRangeObj; + aChange.ReplacedElement >>= xRangeObj; + if( xRangeObj.is() ) + { + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= xRangeObj; + mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); + } + return; + } + + ScRangeList aRangeList; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + aChange = aEvent.Changes[ nIndex ]; + aChange.Accessor >>= sOperation; + uno::Reference< table::XCellRange > xRangeObj; + aChange.ReplacedElement >>= xRangeObj; + if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCaseAscii("cell-change") ) + { + uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY ); + if( xCellRangeAddressable.is() ) + { + ScRange aRange; + ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() ); + aRangeList.Append( aRange ); + } + } + } + + if( (aRangeList.Count() > 0) && mpDocShell ) + { + uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) ); + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= xRanges; + mrVbaEvents.processVbaEvent( WORKSHEET_CHANGE, aArgs ); + } +} + +// ---------------------------------------------------------------------------- + +uno::Reference< frame::XFrame > ScVbaEventsListener::getFrame() +{ + if( !mbDisposed && mxModel.is() ) try + { + uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); + return xController->getFrame(); + } + catch( uno::Exception& ) + { + } + return uno::Reference< frame::XFrame >(); +} + +uno::Reference< awt::XWindow > ScVbaEventsListener::getContainerWindow() +{ + try + { + uno::Reference< frame::XFrame > xFrame( getFrame(), uno::UNO_SET_THROW ); + return xFrame->getContainerWindow(); + } + catch( uno::Exception& ) + { + } + return uno::Reference< awt::XWindow >(); +} + +bool ScVbaEventsListener::isMouseReleased() +{ + if( Window* pWindow = VCLUnoHelper::GetWindow( getContainerWindow() ) ) + { + Window::PointerState aPointerState = pWindow->GetPointerState(); + return (aPointerState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT )) == 0; + } + return false; +} + +IMPL_LINK( ScVbaEventsListener, fireResizeMacro, void*, EMPTYARG ) +{ + if( !mbDisposed && isMouseReleased() ) + processWindowResizeMacro(); + release(); + return 0; +} + +void ScVbaEventsListener::processWindowResizeMacro() +{ + OSL_TRACE( "**** Attempt to FIRE MACRO **** " ); + if( !mbDisposed ) + mrVbaEvents.processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() ); +} + +// ============================================================================ + +ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) : + VbaEventsHelperBase( rArgs, xContext ), + mbOpened( false ) +{ + mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class + mpDoc = mpDocShell ? mpDocShell->GetDocument() : 0; + + if( !mxModel.is() || !mpDocShell || !mpDoc ) + return; + +#define REGISTER_EVENT( eventid, eventname, type, cancelindex, worksheet ) \ + registerEventHandler( eventid, eventname, type, cancelindex, uno::Any( worksheet ) ) + +#define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \ + REGISTER_EVENT( WORKBOOK_##eventid, "Workbook_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, false ) + +#define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \ + REGISTER_EVENT( WORKSHEET_##eventid, "Worksheet_" eventname, EVENTHANDLER_DOCUMENT, cancelindex, true ); \ + REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), "Workbook_Sheet" eventname, EVENTHANDLER_DOCUMENT, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false ) + + // global + REGISTER_EVENT( AUTO_OPEN, "Auto_Open", EVENTHANDLER_GLOBAL, -1, false ); + REGISTER_EVENT( AUTO_CLOSE, "Auto_Close", EVENTHANDLER_GLOBAL, -1, false ); + + // Workbook + REGISTER_WORKBOOK_EVENT( ACTIVATE, "Activate", -1 ); + REGISTER_WORKBOOK_EVENT( DEACTIVATE, "Deactivate", -1 ); + REGISTER_WORKBOOK_EVENT( OPEN, "Open", -1 ); + REGISTER_WORKBOOK_EVENT( BEFORECLOSE, "BeforeClose", 0 ); + REGISTER_WORKBOOK_EVENT( BEFOREPRINT, "BeforePrint", 0 ); + REGISTER_WORKBOOK_EVENT( BEFORESAVE, "BeforeSave", 1 ); + REGISTER_WORKBOOK_EVENT( AFTERSAVE, "AfterSave", -1 ); + REGISTER_WORKBOOK_EVENT( NEWSHEET, "NewSheet", -1 ); + REGISTER_WORKBOOK_EVENT( WINDOWACTIVATE, "WindowActivate", -1 ); + REGISTER_WORKBOOK_EVENT( WINDOWDEACTIVATE, "WindowDeactivate", -1 ); + REGISTER_WORKBOOK_EVENT( WINDOWRESIZE, "WindowResize", -1 ); + + // Worksheet events. All events have a corresponding workbook event. + REGISTER_WORKSHEET_EVENT( ACTIVATE, "Activate", -1 ); + REGISTER_WORKSHEET_EVENT( DEACTIVATE, "Deactivate", -1 ); + REGISTER_WORKSHEET_EVENT( BEFOREDOUBLECLICK, "BeforeDoubleClick", 1 ); + REGISTER_WORKSHEET_EVENT( BEFORERIGHTCLICK, "BeforeRightClick", 1 ); + REGISTER_WORKSHEET_EVENT( CALCULATE, "Calculate", -1 ); + REGISTER_WORKSHEET_EVENT( CHANGE, "Change", -1 ); + REGISTER_WORKSHEET_EVENT( SELECTIONCHANGE, "SelectionChange", -1 ); + REGISTER_WORKSHEET_EVENT( FOLLOWHYPERLINK, "FollowHyperlink", -1 ); + +#undef REGISTER_EVENT +#undef REGISTER_WORKBOOK_EVENT +#undef REGISTER_WORKSHEET_EVENT +} + +ScVbaEventsHelper::~ScVbaEventsHelper() +{ +} + +void SAL_CALL ScVbaEventsHelper::disposing( const lang::EventObject& rSource ) throw (uno::RuntimeException) +{ + mxListener.clear(); + VbaEventsHelperBase::disposing( rSource ); +} + +// protected ------------------------------------------------------------------ + +bool ScVbaEventsHelper::implEventsEnabled() throw (uno::RuntimeException) +{ + // document and document shell are needed during event processing + if( !mpDocShell || !mpDoc ) + throw uno::RuntimeException(); + + // get Application object and check if events are enabled (this is an Excel-only attribute) + uno::Reference< excel::XApplication > xApplication( mxApplication.get(), uno::UNO_QUERY ); + if( !xApplication.is() && mpShell ) + { + uno::Any aVBAGlobals; + mpShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aVBAGlobals ); + uno::Reference< XHelperInterface > xHelperInterface( aVBAGlobals, uno::UNO_QUERY ); + if( xHelperInterface.is() ) + { + xApplication.set( xHelperInterface->Application(), uno::UNO_QUERY ); + mxApplication = xApplication; + } + } + if( !xApplication.is() ) + throw uno::RuntimeException(); + + // return whether event processing is enabled + return xApplication->getEnableEvents(); +} + +bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, + const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException) +{ + // check preconditions for some events, add more events if needed + bool bExecuteEvent = true; + switch( rInfo.mnEventId ) + { + case WORKBOOK_ACTIVATE: + // while loading, framework fires this before 'opened' event, delay it + bExecuteEvent = mbOpened; + break; + case WORKBOOK_OPEN: + bExecuteEvent = !mbOpened; + if( bExecuteEvent ) + { + // execute delayed Activate event too (see above) + rEventQueue.push_back( WORKBOOK_ACTIVATE ); + rEventQueue.push_back( WORKBOOK_WINDOWACTIVATE ); + rEventQueue.push_back( AUTO_OPEN ); + } + break; + case WORKSHEET_SELECTIONCHANGE: + // if selection is not changed, then do not fire the event + bExecuteEvent = mbOpened && isSelectionChanged( rArgs, 0 ); + break; + } + + // add workbook event associated to a sheet event + bool bSheetEvent = false; + rInfo.maUserData >>= bSheetEvent; + if( bSheetEvent && bExecuteEvent ) + rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) ); + + return bExecuteEvent; +} + +uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) throw (lang::IllegalArgumentException) +{ + // fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below + bool bSheetEventAsBookEvent = rInfo.mnEventId > USERDEFINED_START; + sal_Int32 nEventId = bSheetEventAsBookEvent ? (rInfo.mnEventId - USERDEFINED_START) : rInfo.mnEventId; + + uno::Sequence< uno::Any > aVbaArgs; + switch( nEventId ) + { + // *** Workbook *** + + // no arguments + case WORKBOOK_ACTIVATE: + case WORKBOOK_DEACTIVATE: + case WORKBOOK_OPEN: + break; + // 1 arg: cancel + case WORKBOOK_BEFORECLOSE: + case WORKBOOK_BEFOREPRINT: + aVbaArgs.realloc( 1 ); + // current cancel state will be inserted by caller + break; + // 2 args: saveAs, cancel + case WORKBOOK_BEFORESAVE: + aVbaArgs.realloc( 2 ); + checkArgumentType< bool >( rArgs, 0 ); + aVbaArgs[ 0 ] = rArgs[ 0 ]; + // current cancel state will be inserted by caller + break; + // 1 arg: success + case WORKBOOK_AFTERSAVE: + aVbaArgs.realloc( 1 ); + checkArgumentType< bool >( rArgs, 0 ); + aVbaArgs[ 0 ] = rArgs[ 0 ]; + break; + // 1 arg: window + case WORKBOOK_WINDOWACTIVATE: + case WORKBOOK_WINDOWDEACTIVATE: + case WORKBOOK_WINDOWRESIZE: + aVbaArgs.realloc( 1 ); + aVbaArgs[ 0 ] = createWindow(); + break; + // 1 arg: worksheet + case WORKBOOK_NEWSHEET: + aVbaArgs.realloc( 1 ); + aVbaArgs[ 0 ] = createWorksheet( rArgs, 0 ); + break; + + // *** Worksheet *** + + // no arguments + case WORKSHEET_ACTIVATE: + case WORKSHEET_CALCULATE: + case WORKSHEET_DEACTIVATE: + break; + // 1 arg: range + case WORKSHEET_CHANGE: + case WORKSHEET_SELECTIONCHANGE: + aVbaArgs.realloc( 1 ); + aVbaArgs[ 0 ] = createRange( rArgs, 0 ); + break; + // 2 args: range, cancel + case WORKSHEET_BEFOREDOUBLECLICK: + case WORKSHEET_BEFORERIGHTCLICK: + aVbaArgs.realloc( 2 ); + aVbaArgs[ 0 ] = createRange( rArgs, 0 ); + // current cancel state will be inserted by caller + break; + // 1 arg: hyperlink + case WORKSHEET_FOLLOWHYPERLINK: + aVbaArgs.realloc( 1 ); + aVbaArgs[ 0 ] = createHyperlink( rArgs, 0 ); + break; + } + + /* For workbook events associated to sheet events, the workbook event gets + the same arguments but with a Worksheet object in front of them. */ + if( bSheetEventAsBookEvent ) + { + sal_Int32 nLength = aVbaArgs.getLength(); + uno::Sequence< uno::Any > aVbaArgs2( nLength + 1 ); + aVbaArgs2[ 0 ] = createWorksheet( rArgs, 0 ); + for( sal_Int32 nIndex = 0; nIndex < nLength; ++nIndex ) + aVbaArgs2[ nIndex + 1 ] = aVbaArgs[ nIndex ]; + aVbaArgs = aVbaArgs2; + } + + return aVbaArgs; +} + +void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, + const EventHandlerInfo& rInfo, bool /*bSuccess*/, bool bCancel ) throw (uno::RuntimeException) +{ + switch( rInfo.mnEventId ) + { + case WORKBOOK_OPEN: + mbOpened = true; + // register the listeners + if( !mxListener.is() ) + { + mxListener = new ScVbaEventsListener( *this, mxModel, mpDocShell ); + mxListener->startListening(); + } + break; + case WORKBOOK_BEFORECLOSE: + /* Execute Auto_Close only if not cancelled by event handler, but + before UI asks user whether to cancel closing the document. */ + if( !bCancel ) + rEventQueue.push_back( AUTO_CLOSE ); + break; + } +} + +::rtl::OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo, + const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException) +{ + bool bSheetEvent = false; + rInfo.maUserData >>= bSheetEvent; + SCTAB nTab = bSheetEvent ? getTabFromArgs( rArgs, 0 ) : -1; + if( bSheetEvent && (nTab < 0) ) + throw lang::IllegalArgumentException(); + + String aCodeName; + if( bSheetEvent ) + mpDoc->GetCodeName( nTab, aCodeName ); + else + aCodeName = mpDoc->GetCodeName(); + return aCodeName; +} + +// private -------------------------------------------------------------------- + +SCTAB ScVbaEventsHelper::getTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException) +{ + checkArgument( rArgs, nIndex ); + + // first try to extract a sheet index + SCTAB nTab = -1; + if( rArgs[ nIndex ] >>= nTab ) + return nTab; + + // next, try single range object + uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex ); + if( xCellRangeAddressable.is() ) + return xCellRangeAddressable->getRangeAddress().Sheet; + + // at last, try range list + uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex ); + if( xRanges.is() ) + { + uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses(); + if( aRangeAddresses.getLength() > 0 ) + return aRangeAddresses[ 0 ].Sheet; + } + + throw lang::IllegalArgumentException(); +} + +bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false ); + if( ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection ) ) + { + bool bChanged = maOldSelection != pNewCellRanges->GetRangeList(); + maOldSelection = pNewCellRanges->GetRangeList(); + return bChanged; + } + maOldSelection.Clear(); + return true; +} + +uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + // Eventually we will be able to pull the Workbook/Worksheet objects + // directly from basic and register them as listeners + + // extract sheet index, will throw, if parameter is invalid + SCTAB nTab = getTabFromArgs( rArgs, nIndex ); + + // create Workbook + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); + aArgs[ 1 ] <<= mxModel; + uno::Reference< uno::XInterface > xWorkbook( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Workbook", aArgs ), uno::UNO_SET_THROW ); + + // create WorkSheet + String aSheetName; + mpDoc->GetName( nTab, aSheetName ); + aArgs = uno::Sequence< uno::Any >( 3 ); + aArgs[ 0 ] <<= xWorkbook; + aArgs[ 1 ] <<= mxModel; + aArgs[ 2 ] <<= ::rtl::OUString( aSheetName ); + uno::Reference< uno::XInterface > xWorksheet( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Worksheet", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xWorksheet ); +} + +uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex ); + uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex ); + if ( !xRanges.is() && !xRange.is() ) + throw lang::IllegalArgumentException(); + + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent + if ( xRanges.is() ) + aArgs[ 1 ] <<= xRanges; + else + aArgs[ 1 ] <<= xRange; + uno::Reference< uno::XInterface > xVbaRange( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xVbaRange ); +} + +uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= uno::Reference< uno::XInterface >(); // dummy parent + aArgs[ 1 ] <<= getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false ); + uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xHyperlink ); +} + +uno::Any ScVbaEventsHelper::createWindow() const throw (uno::RuntimeException) +{ + uno::Sequence< uno::Any > aArgs( 2 ); + aArgs[ 0 ] <<= createVBAUnoAPIService( mpShell, "ooo.vba.Application" ); + aArgs[ 1 ] <<= mxModel; + uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW ); + return uno::Any( xWindow ); +} + +// ============================================================================ + +namespace vbaeventshelper +{ +namespace sdecl = comphelper::service_decl; +sdecl::class_<ScVbaEventsHelper, sdecl::with_args<true> > serviceImpl; +extern sdecl::ServiceDecl const serviceDecl( + serviceImpl, + "ScVbaEventsHelper", + "com.sun.star.script.vba.VBASpreadsheetEventProcessor" ); +} + +// ============================================================================ diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx new file mode 100755 index 000000000000..a77f5128b3e9 --- /dev/null +++ b/sc/source/ui/vba/vbaeventshelper.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * 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 SC_VBAEVENTS_HXX +#define SC_VBAEVENTS_HXX + +#include <rtl/ref.hxx> +#include <vbahelper/vbaeventshelperbase.hxx> +#include "excelvbahelper.hxx" +#include "rangelst.hxx" + +namespace ooo { namespace vba { namespace excel { class XApplication; } } } + +class ScVbaEventsListener; + +// ============================================================================ + +class ScVbaEventsHelper : public VbaEventsHelperBase +{ +public: + ScVbaEventsHelper( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ); + virtual ~ScVbaEventsHelper(); + + // XEventListener + virtual void SAL_CALL disposing( const css::lang::EventObject& rSource ) throw (css::uno::RuntimeException); + +protected: + virtual bool implEventsEnabled() throw (css::uno::RuntimeException); + virtual bool implPrepareEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::uno::RuntimeException); + virtual css::uno::Sequence< css::uno::Any > implBuildArgumentList( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) throw (css::lang::IllegalArgumentException); + virtual void implPostProcessEvent( EventQueue& rEventQueue, const EventHandlerInfo& rInfo, bool bSuccess, bool bCancel ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString implGetDocumentModuleName( const EventHandlerInfo& rInfo, const css::uno::Sequence< css::uno::Any >& rArgs ) const throw (css::lang::IllegalArgumentException); + +private: + /** Extracts a sheet index from the first element of the passed sequence. The + element may be an integer, or a Calc range or ranges object. */ + static SCTAB getTabFromArgs( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException); + /** Checks if selection has been changed compared to selection of last call. + @return true, if the selection has been changed. */ + bool isSelectionChanged( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + + /** Creates a VBA Worksheet object (the argument must contain a sheet index). */ + css::uno::Any createWorksheet( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + /** Creates a VBA Range object (the argument must contain a UNO range or UNO range list). */ + css::uno::Any createRange( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + /** Creates a VBA Hyperlink object (the argument must contain a UNO cell). */ + css::uno::Any createHyperlink( const css::uno::Sequence< css::uno::Any >& rArgs, sal_Int32 nIndex ) const throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + /** Creates a VBA Window object. */ + css::uno::Any createWindow() const throw (css::uno::RuntimeException); + +private: + mutable css::uno::WeakReference< ov::excel::XApplication > mxApplication; + ::rtl::Reference< ScVbaEventsListener > mxListener; + ScDocShell* mpDocShell; + ScDocument* mpDoc; + ScRangeList maOldSelection; + bool mbOpened; +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbaformatconditions.cxx b/sc/source/ui/vba/vbaformatconditions.cxx index 91d0429326dd..8dd67843ec00 100644 --- a/sc/source/ui/vba/vbaformatconditions.cxx +++ b/sc/source/ui/vba/vbaformatconditions.cxx @@ -45,11 +45,11 @@ static rtl::OUString FORMULA2( RTL_CONSTASCII_USTRINGPARAM("Formula2") ); static rtl::OUString STYLENAME( RTL_CONSTASCII_USTRINGPARAM("StyleName") ); static rtl::OUString sStyleNamePrefix( RTL_CONSTASCII_USTRINGPARAM("Excel_CondFormat") ); -ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntries >& _xSheetConditionalEntries, const uno::Reference< frame::XModel >& xModel ) : ScVbaFormatConditions_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( _xSheetConditionalEntries, uno::UNO_QUERY_THROW ) ), mxSheetConditionalEntries( _xSheetConditionalEntries ) +ScVbaFormatConditions::ScVbaFormatConditions( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntries >& _xSheetConditionalEntries, const uno::Reference< frame::XModel >& /*xModel*/ ) : ScVbaFormatConditions_BASE( xParent, xContext, uno::Reference< container::XIndexAccess >( _xSheetConditionalEntries, uno::UNO_QUERY_THROW ) ), mxSheetConditionalEntries( _xSheetConditionalEntries ) { mxRangeParent.set( xParent, uno::UNO_QUERY_THROW ); - uno::Reference< excel::XWorkbook > xWorkbook = new ScVbaWorkbook( uno::Reference< XHelperInterface >( Application(), uno::UNO_QUERY_THROW ), xContext, xModel ); - mxStyles.set( xWorkbook->Styles( uno::Any() ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XApplication> xApp( Application(), uno::UNO_QUERY_THROW ); + mxStyles.set( xApp->getThisWorkbook()->Styles( uno::Any() ), uno::UNO_QUERY_THROW ); uno::Reference< sheet::XCellRangeAddressable > xCellRange( mxRangeParent->getCellRange(), uno::UNO_QUERY_THROW ); mxParentRangePropertySet.set( xCellRange, uno::UNO_QUERY_THROW ); diff --git a/sc/source/ui/vba/vbaglobals.cxx b/sc/source/ui/vba/vbaglobals.cxx index 0cddacafd194..03f3ecd3c50c 100644 --- a/sc/source/ui/vba/vbaglobals.cxx +++ b/sc/source/ui/vba/vbaglobals.cxx @@ -233,6 +233,7 @@ ScVbaGlobals::getAvailableServiceNames( ) throw (uno::RuntimeException) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Worksheet" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Application" ) ), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "ooo.vba.excel.Hyperlink" ) ), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "com.sun.star.script.vba.VBASpreadsheetEventProcessor" ) ) }; sal_Int32 nExcelServices = ( sizeof( names )/ sizeof( names[0] ) ); sal_Int32 startIndex = serviceNames.getLength(); diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx index a6e8a402425f..464b167df250 100644 --- a/sc/source/ui/vba/vbaname.cxx +++ b/sc/source/ui/vba/vbaname.cxx @@ -232,10 +232,8 @@ ScVbaName::setRefersToR1C1Local( const ::rtl::OUString & rRefersTo ) throw (css: css::uno::Reference< ov::excel::XRange > ScVbaName::getRefersToRange() throw (css::uno::RuntimeException) { - // FIXME: pass proper Worksheet parent uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( - uno::Reference< XHelperInterface >(), mxContext, - mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); return xRange; } diff --git a/sc/source/ui/vba/vbanames.cxx b/sc/source/ui/vba/vbanames.cxx index d074f32b689d..2304874bdb1b 100644 --- a/sc/source/ui/vba/vbanames.cxx +++ b/sc/source/ui/vba/vbanames.cxx @@ -48,7 +48,7 @@ class NamesEnumeration : public EnumerationHelperImpl uno::WeakReference< XHelperInterface > m_xParent; uno::Reference< sheet::XNamedRanges > m_xNames; public: - NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {} + NamesEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel , const uno::Reference< sheet::XNamedRanges >& xNames ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ), m_xNames( xNames ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbapivottables.cxx b/sc/source/ui/vba/vbapivottables.cxx index 05a4201da977..fcbf347a3cd4 100644 --- a/sc/source/ui/vba/vbapivottables.cxx +++ b/sc/source/ui/vba/vbapivottables.cxx @@ -42,7 +42,7 @@ uno::Any DataPilotToPivotTable( const uno::Any& aSource, uno::Reference< uno::XC class PivotTableEnumeration : public EnumerationHelperImpl { public: - PivotTableEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {} + PivotTableEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { @@ -59,7 +59,7 @@ uno::Reference< container::XEnumeration > ScVbaPivotTables::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new PivotTableEnumeration( mxContext, xEnumAccess->createEnumeration() ); + return new PivotTableEnumeration( mxParent, mxContext, xEnumAccess->createEnumeration() ); } uno::Any diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index ccf5a3bc5b54..b50199f025d0 100644..100755 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -202,11 +202,10 @@ double lcl_Round2DecPlaces( double nVal ) return nVal; } -uno::Any lcl_makeRange( uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns ) +uno::Any lcl_makeRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Any aAny, bool bIsRows, bool bIsColumns ) { uno::Reference< table::XCellRange > xCellRange( aAny, uno::UNO_QUERY_THROW ); - // #FIXME need proper (WorkSheet) parent - return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xCellRange, bIsRows, bIsColumns ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xCellRange, bIsRows, bIsColumns ) ) ); } uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSheetCellRanges >& xLocSheetCellRanges, ScDocShell* pDoc ) @@ -227,13 +226,11 @@ uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Re if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xTmpRange( new ScCellRangeObj( pDoc, *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent xRange = new ScVbaRange( xParent, xContext, xTmpRange ); } else { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDoc, aCellRanges ) ); - // #FIXME need proper (WorkSheet) parent xRange = new ScVbaRange( xParent, xContext, xRanges ); } } @@ -269,12 +266,13 @@ SfxItemSet* ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException ) class SingleRangeEnumeration : public EnumerationHelper_BASE { + uno::Reference< XHelperInterface > m_xParent; uno::Reference< table::XCellRange > m_xRange; uno::Reference< uno::XComponentContext > mxContext; bool bHasMore; public: - SingleRangeEnumeration( const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { } + SingleRangeEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< css::uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw ( uno::RuntimeException ) : m_xParent( xParent ), m_xRange( xRange ), mxContext( xContext ), bHasMore( true ) { } virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (uno::RuntimeException) { return bHasMore; } virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { @@ -292,11 +290,12 @@ typedef ::cppu::WeakImplHelper2< container::XIndexAccess, container::XEnumeratio class SingleRangeIndexAccess : public SingleRange_BASE { private: + uno::Reference< XHelperInterface > mxParent; uno::Reference< table::XCellRange > m_xRange; uno::Reference< uno::XComponentContext > mxContext; SingleRangeIndexAccess(); // not defined public: - SingleRangeIndexAccess( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):m_xRange( xRange ), mxContext( xContext ) {} + SingleRangeIndexAccess( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ):mxParent( xParent ), m_xRange( xRange ), mxContext( xContext ) {} // XIndexAccess virtual ::sal_Int32 SAL_CALL getCount() throw (::uno::RuntimeException) { return 1; } virtual uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) @@ -310,7 +309,7 @@ public: virtual ::sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException) { return sal_True; } // XEnumerationAccess - virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxContext, m_xRange ); } + virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException) { return new SingleRangeEnumeration( mxParent, mxContext, m_xRange ); } }; @@ -322,10 +321,10 @@ class RangesEnumerationImpl : public EnumerationHelperImpl bool mbIsColumns; public: - RangesEnumerationImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} + RangesEnumerationImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, bool bIsRows, bool bIsColumns ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { - return lcl_makeRange( m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns ); + return lcl_makeRange( m_xParent, m_xContext, m_xEnumeration->nextElement(), mbIsRows, mbIsColumns ); } }; @@ -335,7 +334,7 @@ class ScVbaRangeAreas : public ScVbaCollectionBaseImpl bool mbIsRows; bool mbIsColumns; public: - ScVbaRangeAreas( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( uno::Reference< XHelperInterface >(), xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} + ScVbaRangeAreas( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess, bool bIsRows, bool bIsColumns ) : ScVbaCollectionBaseImpl( xParent, xContext, xIndexAccess ), mbIsRows( bIsRows ), mbIsColumns( bIsColumns ) {} // XEnumerationAccess virtual uno::Reference< container::XEnumeration > SAL_CALL createEnumeration() throw (uno::RuntimeException); @@ -355,14 +354,13 @@ uno::Reference< container::XEnumeration > SAL_CALL ScVbaRangeAreas::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new RangesEnumerationImpl( mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns ); - + return new RangesEnumerationImpl( mxParent, mxContext, xEnumAccess->createEnumeration(), mbIsRows, mbIsColumns ); } uno::Any ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource ) { - return lcl_makeRange( mxContext, aSource, mbIsRows, mbIsColumns ); + return lcl_makeRange( mxParent, mxContext, aSource, mbIsRows, mbIsColumns ); } // assume that xIf is infact a ScCellRangesBase @@ -618,6 +616,7 @@ public: class CellsEnumeration : public CellsEnumeration_BASE { + uno::WeakReference< XHelperInterface > mxParent; uno::Reference< uno::XComponentContext > mxContext; uno::Reference< XCollection > m_xAreas; vCellPos m_CellPositions; @@ -645,7 +644,7 @@ class CellsEnumeration : public CellsEnumeration_BASE } } public: - CellsEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxContext( xContext ), m_xAreas( xAreas ) + CellsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< XCollection >& xAreas ): mxParent( xParent ), mxContext( xContext ), m_xAreas( xAreas ) { sal_Int32 nItems = m_xAreas->getCount(); for ( sal_Int32 index=1; index <= nItems; ++index ) @@ -664,8 +663,7 @@ public: uno::Reference< table::XCellRange > xRangeArea = getArea( aPos.m_nArea ); uno::Reference< table::XCellRange > xCellRange( xRangeArea->getCellByPosition( aPos.m_nCol, aPos.m_nRow ), uno::UNO_QUERY_THROW ); - // #FIXME need proper (WorkSheet) parent - return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xCellRange ) ) ); + return uno::makeAny( uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, xCellRange ) ) ); } }; @@ -1088,11 +1086,11 @@ public: return uno::Reference< sheet::XSheetCellCursor >( getSpreadSheet()->createCursorByRange( getSheetCellRange() ), uno::UNO_QUERY_THROW ); } - static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference<uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable, sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0, - sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 ) + static uno::Reference< excel::XRange > createRangeFromRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference<uno::XComponentContext >& xContext, + const uno::Reference< table::XCellRange >& xRange, const uno::Reference< sheet::XCellRangeAddressable >& xCellRangeAddressable, + sal_Int32 nStartColOffset = 0, sal_Int32 nStartRowOffset = 0, sal_Int32 nEndColOffset = 0, sal_Int32 nEndRowOffset = 0 ) { - // #FIXME need proper (WorkSheet) parent - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, + return uno::Reference< excel::XRange >( new ScVbaRange( xParent, xContext, xRange->getCellRangeByPosition( xCellRangeAddressable->getRangeAddress().StartColumn + nStartColOffset, xCellRangeAddressable->getRangeAddress().StartRow + nStartRowOffset, @@ -1178,7 +1176,7 @@ bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, S ScVbaRange* -getRangeForName( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) +getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) { ScRangeList aCellRanges; ScRange refRange; @@ -1189,10 +1187,13 @@ getRangeForName( const uno::Reference< XHelperInterface >& xParent, const uno::R if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) ); - return new ScVbaRange( xParent, xContext, xRange ); + uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRange ); + return new ScVbaRange( xFixThisParent, xContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) ); - return new ScVbaRange( xParent, xContext, xRanges ); + + uno::Reference< XHelperInterface > xFixThisParent = excel::getUnoSheetModuleObj( xRanges ); + return new ScVbaRange( xFixThisParent, xContext, xRanges ); } // ---------------------------------------------------------------------------- @@ -1284,12 +1285,12 @@ util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxC // ---------------------------------------------------------------------------- css::uno::Reference< excel::XRange > -ScVbaRange::getRangeObjectForName( const css::uno::Reference< ov::XHelperInterface >& xParent, +ScVbaRange::getRangeObjectForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) { table::CellRangeAddress refAddr; - return getRangeForName( xParent, xContext, sRangeName, pDocSh, refAddr, eConv ); + return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv ); } @@ -1348,13 +1349,13 @@ ScVbaRange::ScVbaRange( uno::Sequence< uno::Any> const & args, uno::Reference< container::XIndexAccess > xIndex; if ( mxRange.is() ) { - xIndex = new SingleRangeIndexAccess( mxContext, mxRange ); + xIndex = new SingleRangeIndexAccess( mxParent, mxContext, mxRange ); } else if ( mxRanges.is() ) { xIndex.set( mxRanges, uno::UNO_QUERY_THROW ); } - m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns ); + m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns ); } ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange, sal_Bool bIsRows, sal_Bool bIsColumns ) throw( lang::IllegalArgumentException ) @@ -1367,8 +1368,8 @@ ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const if ( !xRange.is() ) throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 ); - uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxContext, xRange ) ); - m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns ); + uno::Reference< container::XIndexAccess > xIndex( new SingleRangeIndexAccess( mxParent, mxContext, xRange ) ); + m_Areas = new ScVbaRangeAreas( mxParent, mxContext, xIndex, mbIsRows, mbIsColumns ); } @@ -1377,7 +1378,7 @@ ScVbaRange::ScVbaRange( const uno::Reference< XHelperInterface >& xParent, const { uno::Reference< container::XIndexAccess > xIndex( mxRanges, uno::UNO_QUERY_THROW ); - m_Areas = new ScVbaRangeAreas( mxContext, xIndex, mbIsRows, mbIsColumns ); + m_Areas = new ScVbaRangeAreas( xParent, mxContext, xIndex, mbIsRows, mbIsColumns ); } @@ -1806,11 +1807,11 @@ ScVbaRange::Offset( const ::uno::Any &nRowOff, const uno::Any &nColOff ) throw ( if ( aCellRanges.Count() > 1 ) // Multi-Area { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) ); - return new ScVbaRange( getParent(), mxContext, xRanges ); + return new ScVbaRange( mxParent, mxContext, xRanges ); } // normal range uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) ); - return new ScVbaRange( getParent(), mxContext, xRange ); + return new ScVbaRange( mxParent, mxContext, xRange ); } uno::Reference< excel::XRange > @@ -1831,7 +1832,7 @@ ScVbaRange::CurrentRegion() throw (uno::RuntimeException) helper.getSheetCellCursor(); xSheetCellCursor->collapseToCurrentRegion(); uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW); - return RangeHelper::createRangeFromRange( mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); + return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); } uno::Reference< excel::XRange > @@ -1851,7 +1852,7 @@ ScVbaRange::CurrentArray() throw (uno::RuntimeException) helper.getSheetCellCursor(); xSheetCellCursor->collapseToCurrentArray(); uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xSheetCellCursor, uno::UNO_QUERY_THROW); - return RangeHelper::createRangeFromRange( mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); + return RangeHelper::createRangeFromRange( mxParent, mxContext, helper.getCellRangeFromSheet(), xCellRangeAddressable ); } uno::Any @@ -2069,7 +2070,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr uno::Reference< table::XCellRange > xSheetRange = thisRange.getCellRangeFromSheet(); if( !bIsIndex && !bIsColumnIndex ) // .Cells // #FIXE needs proper parent ( Worksheet ) - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, mxRange ) ); + return uno::Reference< excel::XRange >( new ScVbaRange( mxParent, mxContext, mxRange ) ); sal_Int32 nIndex = --nRow; if( bIsIndex && !bIsColumnIndex ) // .Cells(n) @@ -2087,7 +2088,7 @@ ScVbaRange::Cells( const uno::Any &nRowIndex, const uno::Any &nColumnIndex ) thr --nColumn; nRow = nRow + thisRangeAddress.StartRow; nColumn = nColumn + thisRangeAddress.StartColumn; - return new ScVbaRange( getParent(), mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) ); + return new ScVbaRange( mxParent, mxContext, xSheetRange->getCellRangeByPosition( nColumn, nRow, nColumn, nRow ) ); } void @@ -2239,12 +2240,12 @@ ScVbaRange::Rows(const uno::Any& aIndex ) throw (uno::RuntimeException) throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() ); // return a normal range ( even for multi-selection uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) ); - return new ScVbaRange( getParent(), mxContext, xRange, true ); + return new ScVbaRange( mxParent, mxContext, xRange, true ); } // Rows() - no params if ( m_Areas->getCount() > 1 ) - return new ScVbaRange( getParent(), mxContext, mxRanges, true ); - return new ScVbaRange( getParent(), mxContext, mxRange, true ); + return new ScVbaRange( mxParent, mxContext, mxRanges, true ); + return new ScVbaRange( mxParent, mxContext, mxRange, true ); } uno::Reference< excel::XRange > @@ -2286,9 +2287,8 @@ ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException) throw uno::RuntimeException( rtl::OUString::createFromAscii("Internal failure, illegal param"), uno::Reference< uno::XInterface >() ); } // Columns() - no params - //return new ScVbaRange( getParent(), mxContext, mxRange, false, true ); uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), aRange ) ); - return new ScVbaRange( getParent(), mxContext, xRange, false, true ); + return new ScVbaRange( mxParent, mxContext, xRange, false, true ); } void @@ -2473,7 +2473,7 @@ ScVbaRange::Resize( const uno::Any &RowSize, const uno::Any &ColumnSize ) throw xCursor->collapseToSize( nColumnSize, nRowSize ); uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable(xCursor, ::uno::UNO_QUERY_THROW ); uno::Reference< table::XCellRange > xRange( xSheetRange->getSpreadsheet(), ::uno::UNO_QUERY_THROW ); - return new ScVbaRange( getParent(), mxContext,xRange->getCellRangeByPosition( + return new ScVbaRange( mxParent, mxContext,xRange->getCellRangeByPosition( xCellRangeAddressable->getRangeAddress().StartColumn, xCellRangeAddressable->getRangeAddress().StartRow, xCellRangeAddressable->getRangeAddress().EndColumn, @@ -2563,7 +2563,6 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI // xAddressable now for this range xAddressable.set( xReferrer, uno::UNO_QUERY_THROW ); - if( !Cell1.hasValue() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " Invalid Argument " ) ), @@ -2580,7 +2579,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI Cell1 >>= sName; RangeHelper referRange( xReferrer ); table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress(); - return getRangeForName( getParent(), mxContext, sName, getScDocShell(), referAddress ); + return getRangeForName( mxContext, sName, getScDocShell(), referAddress ); } else @@ -2637,7 +2636,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI } } - return new ScVbaRange( getParent(), mxContext, xCellRange ); + return new ScVbaRange( mxParent, mxContext, xCellRange ); } @@ -2772,10 +2771,10 @@ ScVbaRange::getEntireColumnOrRow( bool bColumn ) throw (uno::RuntimeException) { uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pUnoRangesBase->GetDocShell(), aCellRanges ) ); - return new ScVbaRange( getParent(), mxContext, xRanges, !bColumn, bColumn ); + return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn ); } uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pUnoRangesBase->GetDocShell(), *aCellRanges.First() ) ); - return new ScVbaRange( getParent(), mxContext, xRange, !bColumn, bColumn ); + return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn ); } uno::Reference< excel::XRange > SAL_CALL @@ -3121,7 +3120,7 @@ ScVbaRange::Find( const uno::Any& What, const uno::Any& After, const uno::Any& L uno::Reference< table::XCellRange > xCellRange( xInterface, uno::UNO_QUERY ); if ( xCellRange.is() ) { - uno::Reference< excel::XRange > xResultRange = new ScVbaRange( this, mxContext, xCellRange ); + uno::Reference< excel::XRange > xResultRange = new ScVbaRange( mxParent, mxContext, xCellRange ); if( xResultRange.is() ) { xResultRange->Select(); @@ -3148,7 +3147,7 @@ uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Refere table::CellRangeAddress aRefAddr; if ( !pDocSh ) throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() ); - xKeyRange = getRangeForName( uno::Reference< XHelperInterface >(), xContext, sRangeName, pDocSh, aRefAddr ); + xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr ); } else throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() ); @@ -3582,7 +3581,7 @@ ScVbaRange::createEnumeration() throw (uno::RuntimeException) return new ColumnsRowEnumeration( mxContext, xRange, nElems ); } - return new CellsEnumeration( mxContext, m_Areas ); + return new CellsEnumeration( mxParent, mxContext, m_Areas ); } ::rtl::OUString SAL_CALL @@ -4073,15 +4072,14 @@ ScVbaRange::ApplicationRange( const uno::Reference< uno::XComponentContext >& xC uno::Reference< table::XCellRange > xRange = xReferrer->getReferredCells(); if ( xRange.is() ) { - // #FIXME need proper (WorkSheet) parent - uno::Reference< excel::XRange > xVbRange = new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange ); + uno::Reference< excel::XRange > xVbRange = new ScVbaRange( excel::getUnoSheetModuleObj( xRange ), xContext, xRange ); return xVbRange; } } } uno::Reference< sheet::XSpreadsheetView > xView( getCurrentExcelDoc(xContext)->getCurrentController(), uno::UNO_QUERY ); uno::Reference< table::XCellRange > xSheetRange( xView->getActiveSheet(), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xSheetRange ); + ScVbaRange* pRange = new ScVbaRange( excel::getUnoSheetModuleObj( xSheetRange ), xContext, xSheetRange ); uno::Reference< excel::XRange > xVbSheetRange( pRange ); return pRange->Range( Cell1, Cell2, true ); } @@ -4569,7 +4567,7 @@ ScVbaRange::Insert( const uno::Any& Shift, const uno::Any& CopyOrigin ) throw (u // After the insert ( this range ) actually has moved ScRange aRange( static_cast< SCCOL >( thisAddress.StartColumn ), static_cast< SCROW >( thisAddress.StartRow ), static_cast< SCTAB >( thisAddress.Sheet ), static_cast< SCCOL >( thisAddress.EndColumn ), static_cast< SCROW >( thisAddress.EndRow ), static_cast< SCTAB >( thisAddress.Sheet ) ); uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getDocShellFromRange( mxRange ) , aRange ) ); - uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( getParent(), mxContext, xRange, mbIsRows, mbIsColumns ) ); + uno::Reference< excel::XRange > xVbaRange( new ScVbaRange( mxParent, mxContext, xRange, mbIsRows, mbIsColumns ) ); xVbaRange->PasteSpecial( uno::Any(), uno::Any(), uno::Any(), uno::Any() ); } } @@ -4955,18 +4953,18 @@ ScVbaRange::MergeArea() throw (script::BasicErrorException, uno::RuntimeExceptio if( aCellAddress.StartColumn ==0 && aCellAddress.EndColumn==0 && aCellAddress.StartRow==0 && aCellAddress.EndRow==0) { - return new ScVbaRange( getParent(),mxContext,mxRange ); + return new ScVbaRange( mxParent,mxContext,mxRange ); } else { ScRange refRange( static_cast< SCCOL >( aCellAddress.StartColumn ), static_cast< SCROW >( aCellAddress.StartRow ), static_cast< SCTAB >( aCellAddress.Sheet ), static_cast< SCCOL >( aCellAddress.EndColumn ), static_cast< SCROW >( aCellAddress.EndRow ), static_cast< SCTAB >( aCellAddress.Sheet ) ); uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) ); - return new ScVbaRange( getParent(),mxContext,xRange ); + return new ScVbaRange( mxParent, mxContext,xRange ); } } } - return new ScVbaRange( getParent(),mxContext,mxRange ); + return new ScVbaRange( mxParent, mxContext, mxRange ); } void SAL_CALL @@ -5359,7 +5357,7 @@ ScVbaRange::PreviousNext( bool bIsPrevious ) uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell() , refRange ) ); - return new ScVbaRange( getParent(), mxContext, xRange ); + return new ScVbaRange( mxParent, mxContext, xRange ); } uno::Reference< excel::XRange > SAL_CALL @@ -5442,13 +5440,11 @@ ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( getScDocShell(), *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( getParent(), mxContext, xRange ); + return new ScVbaRange( mxParent, mxContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( getScDocShell(), aCellRanges ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( getParent(), mxContext, xRanges ); + return new ScVbaRange( mxParent, mxContext, xRanges ); } else if ( bIsSingleCell ) { diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index a9147a0d7840..e7488e434f30 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -145,7 +145,6 @@ public: bool isSingleCellRange(); static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( - const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); diff --git a/sc/source/ui/vba/vbaworkbooks.cxx b/sc/source/ui/vba/vbaworkbooks.cxx index 9f9c5dacd796..5298f60e0943 100644 --- a/sc/source/ui/vba/vbaworkbooks.cxx +++ b/sc/source/ui/vba/vbaworkbooks.cxx @@ -46,6 +46,10 @@ #include <com/sun/star/document/XTypeDetection.hpp> #include <com/sun/star/uri/XUriReference.hpp> #include <com/sun/star/uri/XUriReferenceFactory.hpp> +#include <com/sun/star/script/vba/XVBACompatibility.hpp> +#include <com/sun/star/script/vba/XVBAModuleInfo.hpp> +#include <com/sun/star/script/ModuleInfo.hpp> +#include <com/sun/star/script/ModuleType.hpp> #include <sfx2/objsh.hxx> #include <tools/urlobj.hxx> @@ -56,21 +60,100 @@ #include <vbahelper/vbahelper.hxx> #include <hash_map> +#include <vector> #include <osl/file.hxx> using namespace ::ooo::vba; using namespace ::com::sun::star; const sal_Int16 CUSTOM_CHAR = 5; +void setUpDocumentModules( const uno::Reference< sheet::XSpreadsheetDocument >& xDoc ) +{ + uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY ); + ScDocShell* pShell = excel::getDocShell( xModel ); + if ( pShell ) + { + uno::Reference<script::XLibraryContainer> xLibContainer = pShell->GetBasicContainer(); + uno::Reference<script::vba::XVBACompatibility> xVBACompat( xLibContainer, uno::UNO_QUERY_THROW ); + xVBACompat->setVBACompatibilityMode( sal_True ); + String aPrjName( RTL_CONSTASCII_USTRINGPARAM( "VBAProject" ) ); + pShell->GetBasicManager()->SetName( aPrjName ); + + if( xLibContainer.is() ) + { + if( !xLibContainer->hasByName( aPrjName ) ) + xLibContainer->createLibrary( aPrjName ); + uno::Any aLibAny = xLibContainer->getByName( aPrjName ); + uno::Reference< container::XNameContainer > xLib; + aLibAny >>= xLib; + if( xLib.is() ) + { + uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY_THROW ); + uno::Reference< lang::XMultiServiceFactory> xSF( pShell->GetModel(), uno::UNO_QUERY_THROW); + // bootstrap vbaglobals + xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals"))); + uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY_THROW ); + // set up the module info for the workbook and sheets in the nealy created + // spreadsheet + ScDocument* pDoc = pShell->GetDocument(); + String sCodeName = pDoc->GetCodeName(); + if ( sCodeName.Len() == 0 ) + { + sCodeName = String( RTL_CONSTASCII_USTRINGPARAM("ThisWorkbook") ); + pDoc->SetCodeName( sCodeName ); + } + + std::vector< rtl::OUString > sDocModuleNames; + sDocModuleNames.push_back( sCodeName ); + + uno::Reference<container::XNameAccess > xSheets( xDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Sequence< rtl::OUString > sSheets( xSheets->getElementNames() ); + + for ( sal_Int32 index=0; index < sSheets.getLength() ; ++index ) + { + sDocModuleNames.push_back( sSheets[ index ] ); + } + + std::vector<rtl::OUString>::iterator it_end = sDocModuleNames.end(); + + for ( std::vector<rtl::OUString>::iterator it = sDocModuleNames.begin(); it != it_end; ++it ) + { + script::ModuleInfo sModuleInfo; + + sModuleInfo.ModuleObject.set( xVBACodeNamedObjectAccess->getByName( *it ), uno::UNO_QUERY ); + sModuleInfo.ModuleType = script::ModuleType::DOCUMENT; + xVBAModuleInfo->insertModuleInfo( *it, sModuleInfo ); + if( xLib->hasByName( *it ) ) + xLib->replaceByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n") ) ) ); + else + xLib->insertByName( *it, uno::makeAny( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Option VBASupport 1\n" ) ) ) ); + } + } + } + } +} + static uno::Any -getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Any& aApplication ) +getWorkbook( uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheetDocument > &xDoc, const uno::Reference< XHelperInterface >& xParent ) { // FIXME: fine as long as ScVbaWorkbook is stateless ... uno::Reference< frame::XModel > xModel( xDoc, uno::UNO_QUERY ); if( !xModel.is() ) return uno::Any(); - ScVbaWorkbook *pWb = new ScVbaWorkbook( uno::Reference< XHelperInterface >( aApplication, uno::UNO_QUERY_THROW ), xContext, xModel ); + ScDocShell* pShell = excel::getDocShell( xModel ); + if ( pShell ) + { + String sCodeName = pShell->GetDocument()->GetCodeName(); + uno::Reference< uno::XInterface > xIf = getUnoDocModule( sCodeName, pShell ); + if ( xIf.is() ) + { + OSL_TRACE(" *** Returning Module uno Object *** "); + return uno::makeAny( xIf ); + } + } + + ScVbaWorkbook *pWb = new ScVbaWorkbook( xParent, xContext, xModel ); return uno::Any( uno::Reference< excel::XWorkbook > (pWb) ); } @@ -78,12 +161,12 @@ class WorkBookEnumImpl : public EnumerationHelperImpl { uno::Any m_aApplication; public: - WorkBookEnumImpl( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_aApplication( aApplication ) {} + WorkBookEnumImpl( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Any& aApplication ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_aApplication( aApplication ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); - return getWorkbook( m_xContext, xDoc, m_aApplication ); + return getWorkbook( m_xContext, xDoc, m_xParent ); } }; @@ -105,14 +188,14 @@ ScVbaWorkbooks::createEnumeration() throw (uno::RuntimeException) // safer to create an enumeration based on this objects state // rather than one effectively based of the desktop component uno::Reference< container::XEnumerationAccess > xEnumerationAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new WorkBookEnumImpl( mxContext, xEnumerationAccess->createEnumeration(), Application() ); + return new WorkBookEnumImpl( mxParent, mxContext, xEnumerationAccess->createEnumeration(), Application() ); } uno::Any ScVbaWorkbooks::createCollectionObject( const css::uno::Any& aSource ) { uno::Reference< sheet::XSpreadsheetDocument > xDoc( aSource, uno::UNO_QUERY_THROW ); - return getWorkbook( mxContext, xDoc, Application() ); + return getWorkbook( mxContext, xDoc, mxParent ); } @@ -121,8 +204,10 @@ ScVbaWorkbooks::Add() throw (uno::RuntimeException) { uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Add() , uno::UNO_QUERY_THROW ); + // need to set up the document modules ( and vba mode ) here + setUpDocumentModules( xSpreadDoc ); if( xSpreadDoc.is() ) - return getWorkbook( mxContext, xSpreadDoc, Application() ); + return getWorkbook( mxContext, xSpreadDoc, mxParent ); return uno::Any(); } @@ -249,7 +334,7 @@ ScVbaWorkbooks::Open( const rtl::OUString& rFileName, const uno::Any& /*UpdateLi throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Bad Format")), uno::Reference< uno::XInterface >() ); uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( VbaDocumentsBase::Open( rFileName, ReadOnly, sProps ), uno::UNO_QUERY_THROW ); - uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, Application() ); + uno::Any aRet = getWorkbook( mxContext, xSpreadDoc, mxParent ); uno::Reference< excel::XWorkbook > xWBook( aRet, uno::UNO_QUERY ); if ( xWBook.is() ) xWBook->Activate(); diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx index 5b1963e3d242..4eab79813474 100644 --- a/sc/source/ui/vba/vbaworksheet.cxx +++ b/sc/source/ui/vba/vbaworksheet.cxx @@ -60,6 +60,7 @@ #include <com/sun/star/form/FormComponentType.hpp> #include <com/sun/star/form/XFormsSupplier.hpp> #include <ooo/vba/excel/XlEnableSelection.hpp> +#include <ooo/vba/excel/XWorkbook.hpp> #include <ooo/vba/XControlProvider.hpp> #include <comphelper/processfactory.hxx> @@ -672,24 +673,26 @@ ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeExceptio } uno::Any SAL_CALL +ScVbaWorksheet::Names( const css::uno::Any& aIndex ) throw (uno::RuntimeException) +{ + uno::Reference< excel::XWorkbook > xWorkbook( getParent(), uno::UNO_QUERY_THROW ); + return xWorkbook->Names( aIndex ); +} + +uno::Any SAL_CALL ScVbaWorksheet::OLEObjects( const uno::Any& Index ) throw (uno::RuntimeException) { - ScVbaOLEObjects* aOleObjects; uno::Reference< sheet::XSpreadsheet > xSpreadsheet( getSheet(), uno::UNO_QUERY_THROW ); uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupplier( xSpreadsheet, uno::UNO_QUERY_THROW ); uno::Reference< drawing::XDrawPage > xDrawPage( xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndexAccess( xDrawPage, uno::UNO_QUERY_THROW ); - aOleObjects = new ScVbaOLEObjects( this, mxContext, xIndexAccess ); + uno::Reference< excel::XOLEObjects >xOleObjects( new ScVbaOLEObjects( this, mxContext, xIndexAccess ) ); if( Index.hasValue() ) - { - return aOleObjects->Item( Index, uno::Any() ); - } - else - { - return uno::makeAny( uno::Reference< excel::XOLEObjects> ( aOleObjects ) ); - } + return xOleObjects->Item( Index, uno::Any() ); + return uno::Any( xOleObjects ); } + uno::Any SAL_CALL ScVbaWorksheet::Shapes( const uno::Any& aIndex ) throw (uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx index d07cc1a8d55c..196a195258d7 100644 --- a/sc/source/ui/vba/vbaworksheet.hxx +++ b/sc/source/ui/vba/vbaworksheet.hxx @@ -129,6 +129,7 @@ public: virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Names( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx index 60cf7b904026..5344e6b3a9be 100644 --- a/sc/source/ui/vba/vbaworksheets.cxx +++ b/sc/source/ui/vba/vbaworksheets.cxx @@ -52,6 +52,7 @@ #include "vbaglobals.hxx" #include "vbaworksheet.hxx" #include "vbaworkbook.hxx" +#include <unonames.hxx> using namespace ::ooo::vba; using namespace ::com::sun::star; @@ -63,6 +64,27 @@ typedef ::cppu::WeakImplHelper3< container::XNameAccess, container::XIndexAccess // (as added ) of the items typedef std::vector< uno::Reference< sheet::XSpreadsheet > > SheetMap; + +// #FIXME #TODO the implementation of the Sheets collections sucks, +// e.g. there is no support for tracking sheets added/removed from the collection + +uno::Reference< uno::XInterface > +lcl_getModulAsUnoObject( const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) +{ + uno::Reference< uno::XInterface > xRet; + if ( !xSheet.is() ) + throw uno::RuntimeException(); + uno::Reference< beans::XPropertySet > xProps( xSheet, uno::UNO_QUERY_THROW ); + rtl::OUString sName; + xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_CODENAME ) ) ) >>= sName; + + ScDocShell* pShell = excel::getDocShell( xModel ); + + if ( pShell ) + xRet = getUnoDocModule( sName, pShell ); + return xRet; +} + class WorkSheetsEnumeration : public SheetEnumeration_BASE { SheetMap mSheetMap; @@ -145,14 +167,24 @@ public: class SheetsEnumeration : public EnumerationHelperImpl { uno::Reference< frame::XModel > m_xModel; - uno::WeakReference< XHelperInterface > m_xParent; public: - SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ), m_xModel( xModel ), m_xParent( xParent ) {} + SheetsEnumeration( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration, const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xParent, xContext, xEnumeration ), m_xModel( xModel ) {} virtual uno::Any SAL_CALL nextElement( ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { uno::Reference< sheet::XSpreadsheet > xSheet( m_xEnumeration->nextElement(), uno::UNO_QUERY_THROW ); - return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) ) ); + uno::Reference< uno::XInterface > xIf = lcl_getModulAsUnoObject( xSheet, m_xModel ); + uno::Any aRet; + if ( !xIf.is() ) + { + // if the Sheet is in a document created by the api unfortunately ( at the + // moment, it actually wont have the special Document modules + uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( m_xParent, m_xContext, xSheet, m_xModel ) ); + aRet <<= xNewSheet; + } + else + aRet <<= xIf; + return aRet; } }; @@ -188,7 +220,18 @@ uno::Any ScVbaWorksheets::createCollectionObject( const uno::Any& aSource ) { uno::Reference< sheet::XSpreadsheet > xSheet( aSource, uno::UNO_QUERY ); - return uno::makeAny( uno::Reference< excel::XWorksheet > ( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) ) ); + uno::Reference< XInterface > xIf = lcl_getModulAsUnoObject( xSheet, mxModel ); + uno::Any aRet; + if ( !xIf.is() ) + { + // if the Sheet is in a document created by the api unfortunately ( at the + // moment, it actually wont have the special Document modules + uno::Reference< excel::XWorksheet > xNewSheet( new ScVbaWorksheet( getParent(), mxContext, xSheet, mxModel ) ); + aRet <<= xNewSheet; + } + else + aRet <<= xIf; + return aRet; } // XWorksheets diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index db72d87f30a2..0f07b8772254 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -69,6 +69,8 @@ #include <com/sun/star/sheet/MemberResultFlags.hpp> #include <com/sun/star/awt/KeyModifier.hpp> #include <com/sun/star/awt/MouseButton.hpp> +#include <com/sun/star/script/vba/VBAEventId.hpp> +#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include "gridwin.hxx" #include "tabvwsh.hxx" @@ -119,6 +121,7 @@ #include "tabprotection.hxx" #include "postit.hxx" #include "dpcontrol.hxx" +#include "cellsuno.hxx" #include "drawview.hxx" #include <svx/sdrpagewindow.hxx> @@ -366,6 +369,32 @@ void lcl_UnLockComment( ScDrawView* pView, SdrPageView* pPV, SdrModel* pDrDoc, c } } +sal_Bool lcl_GetHyperlinkCell(ScDocument* pDoc, SCCOL& rPosX, SCROW& rPosY, SCTAB nTab, ScBaseCell*& rpCell ) +{ + BOOL bFound = FALSE; + do + { + pDoc->GetCell( rPosX, rPosY, nTab, rpCell ); + if ( !rpCell || rpCell->GetCellType() == CELLTYPE_NOTE ) + { + if ( rPosX <= 0 ) + return FALSE; // alles leer bis links + else + --rPosX; // weitersuchen + } + else if ( rpCell->GetCellType() == CELLTYPE_EDIT) + bFound = TRUE; + else if (rpCell->GetCellType() == CELLTYPE_FORMULA && + static_cast<ScFormulaCell*>(rpCell)->IsHyperLinkCell()) + bFound = TRUE; + else + return FALSE; // andere Zelle + } + while ( !bFound ); + + return bFound; +} + // --------------------------------------------------------------------------- // WB_DIALOGCONTROL noetig fuer UNO-Controls ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhichPos ) @@ -2100,6 +2129,30 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt ) { nMouseStatus = SC_GM_NONE; // keinen Doppelklick anfangen ScGlobal::OpenURL( aUrl, aTarget ); + + // fire worksheet_followhyperlink event + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = pDoc->GetVbaEventProcessor(); + if( xVbaEvents.is() ) try + { + Point aPos = rMEvt.GetPosPixel(); + SCsCOL nPosX; + SCsROW nPosY; + SCTAB nTab = pViewData->GetTabNo(); + pViewData->GetPosFromPixel( aPos.X(), aPos.Y(), eWhich, nPosX, nPosY ); + ScBaseCell* pCell = NULL; + if( lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ) ) + { + ScAddress aCellPos( nPosX, nPosY, nTab ); + uno::Reference< table::XCell > xCell( new ScCellObj( pViewData->GetDocShell(), aCellPos ) ); + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= xCell; + xVbaEvents->processVbaEvent( script::vba::VBAEventId::WORKSHEET_FOLLOWHYPERLINK, aArgs ); + } + } + catch( uno::Exception& ) + { + } + return; } } @@ -4818,26 +4871,9 @@ BOOL ScGridWindow::GetEditUrlOrError( BOOL bSpellErr, const Point& rPos, ScDocument* pDoc = pDocSh->GetDocument(); ScBaseCell* pCell = NULL; - BOOL bFound = FALSE; - do - { - pDoc->GetCell( nPosX, nPosY, nTab, pCell ); - if ( !pCell || pCell->GetCellType() == CELLTYPE_NOTE ) - { - if ( nPosX <= 0 ) - return FALSE; // alles leer bis links - else - --nPosX; // weitersuchen - } - else if ( pCell->GetCellType() == CELLTYPE_EDIT) - bFound = TRUE; - else if (pCell->GetCellType() == CELLTYPE_FORMULA && - static_cast<ScFormulaCell*>(pCell)->IsHyperLinkCell()) - bFound = TRUE; - else - return FALSE; // andere Zelle - } - while ( !bFound ); + BOOL bFound = lcl_GetHyperlinkCell( pDoc, nPosX, nPosY, nTab, pCell ); + if( !bFound ) + return FALSE; ScHideTextCursor aHideCursor( pViewData, eWhich ); // before GetEditArea (MapMode is changed) diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx index 1faa105d2bd7..d5816ecdd289 100644 --- a/sc/source/ui/view/scextopt.cxx +++ b/sc/source/ui/view/scextopt.cxx @@ -197,20 +197,27 @@ ScExtTabSettings& ScExtDocOptions::GetOrCreateTabSettings( SCTAB nTab ) return mxImpl->maTabSett.GetOrCreateTabSettings( nTab ); } -size_t ScExtDocOptions::GetCodeNameCount() const +SCTAB ScExtDocOptions::GetCodeNameCount() const { - return mxImpl->maCodeNames.size(); + return static_cast< SCTAB >( mxImpl->maCodeNames.size() ); } -const String& ScExtDocOptions::GetCodeName( size_t nIdx ) const +const String& ScExtDocOptions::GetCodeName( SCTAB nTab ) const { - DBG_ASSERT( nIdx < GetCodeNameCount(), "ScExtDocOptions::GetCodeName - invalid index" ); - return (nIdx < GetCodeNameCount()) ? mxImpl->maCodeNames[ nIdx ] : EMPTY_STRING; + DBG_ASSERT( (0 <= nTab) && (nTab < GetCodeNameCount()), "ScExtDocOptions::GetCodeName - invalid sheet index" ); + return ((0 <= nTab) && (nTab < GetCodeNameCount())) ? mxImpl->maCodeNames[ static_cast< size_t >( nTab ) ] : EMPTY_STRING; } -void ScExtDocOptions::AppendCodeName( const String& rCodeName ) +void ScExtDocOptions::SetCodeName( SCTAB nTab, const String& rCodeName ) { - mxImpl->maCodeNames.push_back( rCodeName ); + DBG_ASSERT( nTab >= 0, "ScExtDocOptions::SetCodeName - invalid sheet index" ); + if( nTab >= 0 ) + { + size_t nIndex = static_cast< size_t >( nTab ); + if( nIndex >= mxImpl->maCodeNames.size() ) + mxImpl->maCodeNames.resize( nIndex + 1 ); + mxImpl->maCodeNames[ nIndex ] = rCodeName; + } } // ============================================================================ diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 86f68a1878cc..90bfe0c24e5c 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -1682,6 +1682,7 @@ void ScTabView::SetTabNo( SCTAB nTab, BOOL bNew, BOOL bExtendSelection ) } TabChanged(); // DrawView + aViewData.GetViewShell()->WindowChanged(); // falls das aktive Fenster anders ist if ( !bUnoRefDialog ) aViewData.GetViewShell()->DisconnectAllClients(); // important for floating frames diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 34fbbfdad5b5..a125cbea6f50 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -28,8 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - // INCLUDE --------------------------------------------------------------- #include "scitems.hxx" diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml index 855db09ff50c..a6b772cca012 100644 --- a/sc/uiconfig/scalc/menubar/menubar.xml +++ b/sc/uiconfig/scalc/menubar/menubar.xml @@ -92,6 +92,7 @@ <menu:menuitem menu:id=".uno:Move"/> <menu:menuitem menu:id=".uno:SelectTables"/> <menu:menuitem menu:id=".uno:Remove"/> + <menu:menuitem menu:id=".uno:TableEvents"/> </menu:menupopup> </menu:menu> <menu:menu menu:id=".uno:DelBreakMenu"> |