diff options
Diffstat (limited to 'sc/source/ui/docshell/docsh.cxx')
-rw-r--r--[-rwxr-xr-x] | sc/source/ui/docshell/docsh.cxx | 181 |
1 files changed, 150 insertions, 31 deletions
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 !!! |