summaryrefslogtreecommitdiff
path: root/sc/source/ui/docshell/docsh.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/docshell/docsh.cxx')
-rw-r--r--[-rwxr-xr-x]sc/source/ui/docshell/docsh.cxx181
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 !!!