diff options
author | Mikhail Voytenko <mav@openoffice.org> | 2010-07-27 11:57:42 +0200 |
---|---|---|
committer | Mikhail Voytenko <mav@openoffice.org> | 2010-07-27 11:57:42 +0200 |
commit | e314076dceca46ebb3e08509658ff5150b14f358 (patch) | |
tree | 6e9bd0122beb15df886a860519cf0c764a1116e8 | |
parent | 80b8a7ebe17abd51f40cc5faa3fdcf6fd02e5e49 (diff) | |
parent | f6238c8dd45c32f93cb83b65aa908617f0535252 (diff) |
mib17: merging
-rw-r--r-- | sc/inc/document.hxx | 6 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 20 | ||||
-rw-r--r-- | sc/source/core/data/documen3.cxx | 22 | ||||
-rw-r--r-- | sc/source/filter/excel/excimp8.cxx | 11 | ||||
-rw-r--r-- | sc/source/ui/docshell/docsh.cxx | 80 | ||||
-rw-r--r-- | sc/source/ui/unoobj/servuno.cxx | 51 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbaeventshelper.cxx | 288 | ||||
-rwxr-xr-x | sc/source/ui/vba/vbaeventshelper.hxx | 5 | ||||
-rw-r--r-- | sc/source/ui/view/makefile.mk | 1 | ||||
-rw-r--r-- | sc/source/ui/view/tabview3.cxx | 1 |
10 files changed, 210 insertions, 275 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index dc68989b1..0deedd897 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1759,8 +1759,10 @@ public: void GetSortParam( ScSortParam& rParam, SCTAB nTab ); void SetSortParam( ScSortParam& rParam, SCTAB nTab ); - com::sun::star::uno::Reference< com::sun::star::script::vba::XVBAEventProcessor > - GetVbaEventProcessor() const; + 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 ); diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index f80819997..4e39ba4b2 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -51,8 +51,6 @@ #include <tools/list.hxx> #include <rtl/crc.h> #include <basic/basmgr.hxx> -#include <com/sun/star/script/vba/XVBAEventProcessor.hpp> -#include <vbahelper/vbaaccesshelper.hxx> #include "document.hxx" #include "table.hxx" @@ -1293,24 +1291,6 @@ void ScDocument::RemoveLookupCache( ScLookupCache & rCache ) } } -uno::Reference< script::vba::XVBAEventProcessor > ScDocument::GetVbaEventProcessor() const -{ - if( !mxVbaEvents.is() && pShell && IsInVBAMode() ) - { - try - { - uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY_THROW ); - uno::Sequence< uno::Any > aArgs(1); - aArgs[0] <<= xModel; - mxVbaEvents.set( ooo::vba::createVBAUnoAPIServiceWithArgs( pShell, "com.sun.star.script.vba.VBASpreadsheetEventProcessor" , aArgs ), uno::UNO_QUERY_THROW ); - } - catch( uno::Exception& ) - { - } - } - return mxVbaEvents; -} - void ScDocument::ClearLookupCaches() { if( pLookupCacheMapImpl ) diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 33f68a0fe..beaae25d4 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -501,20 +501,16 @@ bool ScDocument::HasSheetEventScript( SCTAB nTab, sal_Int32 nEvent, bool bWithVb if ( pEvents && pEvents->GetScript( nEvent ) ) return true; // check if VBA event handlers exist - if (bWithVbaEvents) + if (bWithVbaEvents && mxVbaEvents.is()) try + { + 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& ) { - uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = GetVbaEventProcessor(); - if ( xVbaEvents.is() ) try - { - uno::Sequence< uno::Any > aArgs( 1 ); - aArgs[ 0 ] <<= nTab; - if (xVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent ), aArgs ) || - xVbaEvents->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent ), uno::Sequence< uno::Any >() )) - return true; - } - catch( uno::Exception& ) - { - } } } return false; diff --git a/sc/source/filter/excel/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index 46e97e4b1..a601d7663 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -242,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 ); } } diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 271ad10ac..df6ccf9c5 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -68,6 +68,7 @@ #include <com/sun/star/script/vba/XVBAEventProcessor.hpp> #include <basic/sbstar.hxx> #include <basic/basmgr.hxx> +#include <vbahelper/vbaaccesshelper.hxx> #include "scabstdlg.hxx" //CHINA001 #include <sot/formats.hxx> @@ -272,11 +273,6 @@ void ScDocShell::BeforeXMLLoading() { aDocument.DisableIdle( TRUE ); - // suppress VBA events when loading the xml - uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor(); - if( xVbaEvents.is() ) - xVbaEvents->setIgnoreEvents( sal_True ); - // prevent unnecessary broadcasts and updates DBG_ASSERT(pModificator == NULL, "The Modificator should not exist"); pModificator = new ScDocShellModificator( *this ); @@ -361,34 +357,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 ] ); -#if 0 // this should be controlled by a compatibility mode - // suppress VBA events when loading the xml - uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents = aDocument.GetVbaEventProcessor(); - if( xVbaEvents.is() ) - xVbaEvents->setIgnoreEvents( sal_False ); -#endif -#endif + aDocument.SetImportingXML( FALSE ); aDocument.EnableExecuteLink( true ); aDocument.EnableUndo( TRUE ); @@ -567,6 +536,17 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) xVbaEvents->processVbaEvent( WORKBOOK_AFTERSAVE, aArgs ); } break; + case SFX_EVENT_CLOSEDOC: + { + // explicitly fire WindowDeactivate and Deactivate on closing + uno::Sequence< uno::Any > aArgs; + xVbaEvents->processVbaEvent( WORKBOOK_WINDOWDEACTIVATE, aArgs ); + xVbaEvents->processVbaEvent( WORKBOOK_DEACTIVATE, aArgs ); + // event processor will remove all listeners on destruction + xVbaEvents.clear(); + aDocument.SetVbaEventProcessor( xVbaEvents ); + } + break; } } } @@ -632,6 +612,40 @@ 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 + uno::Reference< lang::XMultiServiceFactory > xFactory( xModel, uno::UNO_QUERY_THROW ); + xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAGlobals" ) ) ); + + // 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 + if( BasicManager* pAppMgr = SFX_APP()->GetBasicManager() ) + pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", uno::Any( xModel ) ); + + // create the VBA document event processor + uno::Sequence< uno::Any > aArgs( 1 ); + aArgs[ 0 ] <<= xModel; + uno::Reference< script::vba::XVBAEventProcessor > xVbaEvents( + 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: diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx index 0e5a2100d..48011939e 100644 --- a/sc/source/ui/unoobj/servuno.cxx +++ b/sc/source/ui/unoobj/servuno.cxx @@ -74,15 +74,6 @@ using namespace ::com::sun::star; -bool isInVBAMode( ScDocShell& rDocSh ) -{ - uno::Reference<script::XLibraryContainer> xLibContainer = rDocSh.GetBasicContainer(); - uno::Reference<script::XVBACompat> xVBACompat( xLibContainer, uno::UNO_QUERY ); - if ( xVBACompat.is() ) - return xVBACompat->getVBACompatModeOn(); - return false; -} - class ScVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper1< container::XNameAccess > { uno::Any maWorkbook; @@ -547,6 +538,7 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( break; case SC_SERVICE_OPCODEMAPPER: + if (pDocShell) { ScDocument* pDoc = pDocShell->GetDocument(); ScAddress aAddress; @@ -556,44 +548,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() && isInVBAMode( *pDocShell ) ) - { - // 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/vba/vbaeventshelper.cxx b/sc/source/ui/vba/vbaeventshelper.cxx index 60ec018df..5c64edaae 100755 --- a/sc/source/ui/vba/vbaeventshelper.cxx +++ b/sc/source/ui/vba/vbaeventshelper.cxx @@ -40,8 +40,7 @@ #include <ooo/vba/excel/XApplication.hpp> -#include <cppuhelper/implbase1.hxx> -#include <cppuhelper/implbase3.hxx> +#include <cppuhelper/implbase4.hxx> #include <toolkit/unohlp.hxx> #include <vbahelper/helperdecl.hxx> #include <vcl/svapp.hxx> @@ -56,101 +55,19 @@ using namespace ::ooo::vba; // ============================================================================ -typedef ::cppu::WeakImplHelper1< util::XChangesListener > ScVbaChangesListener_BASE; - -class ScVbaChangesListener : public ScVbaChangesListener_BASE -{ -public: - ScVbaChangesListener( ScVbaEventsHelper* pHelper, ScDocShell* pDocShell ); - - virtual void SAL_CALL changesOccurred( const util::ChangesEvent& aEvent ) throw (uno::RuntimeException); - virtual void SAL_CALL disposing( const lang::EventObject& aSource ) throw (uno::RuntimeException); - -private: - ScVbaEventsHelper* mpVbaEvents; - ScDocShell* mpDocShell; -}; - -// ---------------------------------------------------------------------------- - -ScVbaChangesListener::ScVbaChangesListener( ScVbaEventsHelper* pHelper, ScDocShell* pDocShell ) : - mpVbaEvents( pHelper ), - mpDocShell( pDocShell ) -{ -} - -void SAL_CALL ScVbaChangesListener::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; - mpVbaEvents->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; - mpVbaEvents->processVbaEvent( WORKSHEET_CHANGE, aArgs ); - } -} - -void SAL_CALL ScVbaChangesListener::disposing( const lang::EventObject& /*aSource*/ ) throw(uno::RuntimeException) -{ -} - -// ============================================================================ - -typedef ::cppu::WeakImplHelper3< - awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener > ScVbaWindowListener_BASE; +typedef ::cppu::WeakImplHelper4< + awt::XWindowListener, util::XCloseListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventsListener_BASE; // This class is to process Workbook window related event -class ScVbaWindowListener : public ScVbaWindowListener_BASE +class ScVbaEventsListener : public ScVbaEventsListener_BASE { public : - ScVbaWindowListener( ScVbaEventsHelper* pHelper, const uno::Reference< frame::XModel >& rxModel ); - virtual ~ScVbaWindowListener(); + 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); @@ -165,6 +82,9 @@ public : // 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(); @@ -174,31 +94,36 @@ private: private: ::osl::Mutex maMutex; - ScVbaEventsHelper* mpVbaEvents; + ScVbaEventsHelper& mrVbaEvents; uno::Reference< frame::XModel > mxModel; + ScDocShell* mpDocShell; bool mbWindowResized; bool mbBorderChanged; + bool mbDisposed; }; // ---------------------------------------------------------------------------- -ScVbaWindowListener::ScVbaWindowListener( ScVbaEventsHelper* pHelper, const uno::Reference< frame::XModel >& rxModel ) : - mpVbaEvents( pHelper ), +ScVbaEventsListener::ScVbaEventsListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) : + mrVbaEvents( rVbaEvents ), mxModel( rxModel ), - mbWindowResized( sal_False ), - mbBorderChanged( sal_False ) + mpDocShell( pDocShell ), + mbWindowResized( false ), + mbBorderChanged( false ), + mbDisposed( !rxModel.is() ) { - OSL_TRACE( "ScVbaWindowListener::ScVbaWindowListener( 0x%x ) - ctor ", this ); + OSL_TRACE( "ScVbaEventsListener::ScVbaEventsListener( 0x%x ) - ctor ", this ); } -ScVbaWindowListener::~ScVbaWindowListener() +ScVbaEventsListener::~ScVbaEventsListener() { - OSL_TRACE( "ScVbaWindowListener::~ScVbaWindowListener( 0x%x ) - dtor ", this ); + OSL_TRACE( "ScVbaEventsListener::~ScVbaEventsListener( 0x%x ) - dtor ", this ); + stopListening(); } -void ScVbaWindowListener::startListening() +void ScVbaEventsListener::startListening() { - if( mxModel.is() ) + if( !mbDisposed ) { // add window listener try @@ -227,12 +152,21 @@ void ScVbaWindowListener::startListening() 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 ScVbaWindowListener::stopListening() +void ScVbaEventsListener::stopListening() { - if( mxModel.is() ) + if( !mbDisposed ) { try { @@ -258,80 +192,141 @@ void ScVbaWindowListener::stopListening() catch( uno::Exception& ) { } + try + { + uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); + xChangesNotifier->removeChangesListener( this ); + } + catch( uno::Exception& ) + { + } } - mpVbaEvents = 0; + mbDisposed = true; } -void SAL_CALL ScVbaWindowListener::windowResized( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventsListener::windowResized( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) { ::osl::MutexGuard aGuard( maMutex ); // Workbook_window_resize event mbWindowResized = true; - if( mbBorderChanged ) + 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, ScVbaWindowListener, fireResizeMacro ), 0 ); + Application::PostUserEvent( LINK( this, ScVbaEventsListener, fireResizeMacro ), 0 ); } } } -void SAL_CALL ScVbaWindowListener::windowMoved( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventsListener::windowMoved( const awt::WindowEvent& /*aEvent*/ ) throw ( uno::RuntimeException ) { // not interest this time } -void SAL_CALL ScVbaWindowListener::windowShown( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventsListener::windowShown( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) { // not interest this time } -void SAL_CALL ScVbaWindowListener::windowHidden( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventsListener::windowHidden( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) { // not interest this time } -void SAL_CALL ScVbaWindowListener::disposing( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) +void SAL_CALL ScVbaEventsListener::disposing( const lang::EventObject& /*aEvent*/ ) throw ( uno::RuntimeException ) { ::osl::MutexGuard aGuard( maMutex ); - OSL_TRACE( "ScVbaWindowListener::disposing( 0x%x )", this ); - mpVbaEvents = 0; + OSL_TRACE( "ScVbaEventsListener::disposing( 0x%x )", this ); + mbDisposed = true; } -void SAL_CALL ScVbaWindowListener::queryClosing( const lang::EventObject& /*Source*/, sal_Bool /*GetsOwnership*/ ) throw (util::CloseVetoException, uno::RuntimeException) +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 ScVbaWindowListener::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) +void SAL_CALL ScVbaEventsListener::notifyClosing( const lang::EventObject& /*Source*/ ) throw (uno::RuntimeException) { ::osl::MutexGuard aGuard( maMutex ); stopListening(); } -void SAL_CALL ScVbaWindowListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& /*aObject*/, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException) +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( mbWindowResized ) + 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, ScVbaWindowListener, fireResizeMacro ), 0 ); + 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 > ScVbaWindowListener::getFrame() +uno::Reference< frame::XFrame > ScVbaEventsListener::getFrame() { - if( mpVbaEvents && mxModel.is() ) try + if( !mbDisposed && mxModel.is() ) try { uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW ); return xController->getFrame(); @@ -342,7 +337,7 @@ uno::Reference< frame::XFrame > ScVbaWindowListener::getFrame() return uno::Reference< frame::XFrame >(); } -uno::Reference< awt::XWindow > ScVbaWindowListener::getContainerWindow() +uno::Reference< awt::XWindow > ScVbaEventsListener::getContainerWindow() { try { @@ -355,7 +350,7 @@ uno::Reference< awt::XWindow > ScVbaWindowListener::getContainerWindow() return uno::Reference< awt::XWindow >(); } -bool ScVbaWindowListener::isMouseReleased() +bool ScVbaEventsListener::isMouseReleased() { if( Window* pWindow = VCLUnoHelper::GetWindow( getContainerWindow() ) ) { @@ -365,27 +360,26 @@ bool ScVbaWindowListener::isMouseReleased() return false; } -IMPL_LINK( ScVbaWindowListener, fireResizeMacro, void*, EMPTYARG ) +IMPL_LINK( ScVbaEventsListener, fireResizeMacro, void*, EMPTYARG ) { - if( mpVbaEvents && isMouseReleased() ) + if( !mbDisposed && isMouseReleased() ) processWindowResizeMacro(); release(); return 0; } -void ScVbaWindowListener::processWindowResizeMacro() +void ScVbaEventsListener::processWindowResizeMacro() { OSL_TRACE( "**** Attempt to FIRE MACRO **** " ); - if( mpVbaEvents ) - mpVbaEvents->processVbaEvent( WORKBOOK_WINDOWRESIZE, uno::Sequence< uno::Any >() ); + 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 ), - mbClosed( false ) + mbOpened( false ) { mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class mpDoc = mpDocShell ? mpDocShell->GetDocument() : 0; @@ -393,17 +387,6 @@ ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, co if( !mxModel.is() || !mpDocShell || !mpDoc ) return; - // add worksheet change listener - try - { - uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW ); - uno::Reference< util::XChangesListener > xChangesListener( new ScVbaChangesListener( this, mpDocShell ) ); - xChangesNotifier->addChangesListener( xChangesListener ); - } - catch( uno::Exception& ) - { - } - #define REGISTER_EVENT( eventid, eventname, type, cancelindex, worksheet ) \ registerEventHandler( eventid, eventname, type, cancelindex, uno::Any( worksheet ) ) @@ -499,13 +482,9 @@ bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue, rEventQueue.push_back( AUTO_OPEN ); } break; - case WORKBOOK_DEACTIVATE: - if( mbClosed ) - rEventQueue.push_back( WORKBOOK_WINDOWDEACTIVATE ); - break; case WORKSHEET_SELECTIONCHANGE: // if selection is not changed, then do not fire the event - bExecuteEvent = mbOpened && !mbClosed && isSelectionChanged( rArgs, 0 ); + bExecuteEvent = mbOpened && isSelectionChanged( rArgs, 0 ); break; } @@ -616,25 +595,18 @@ void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue, { case WORKBOOK_OPEN: mbOpened = true; - // register the window listener - if( !mxWindowListener.is() ) + // register the listeners + if( !mxListener.is() ) { - mxWindowListener = new ScVbaWindowListener( this, mxModel ); - mxWindowListener->startListening(); + mxListener = new ScVbaEventsListener( *this, mxModel, mpDocShell ); + mxListener->startListening(); } break; case WORKBOOK_BEFORECLOSE: - mbClosed = !bCancel; - if( mbClosed ) - { - // execute Auto_Close if not cancelled + /* 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 ); - if( mxWindowListener.is() ) - { - mxWindowListener->stopListening(); - mxWindowListener.clear(); - } - } break; } } diff --git a/sc/source/ui/vba/vbaeventshelper.hxx b/sc/source/ui/vba/vbaeventshelper.hxx index 39c91e31a..66db22f90 100755 --- a/sc/source/ui/vba/vbaeventshelper.hxx +++ b/sc/source/ui/vba/vbaeventshelper.hxx @@ -35,7 +35,7 @@ namespace ooo { namespace vba { namespace excel { class XApplication; } } } -class ScVbaWindowListener; +class ScVbaEventsListener; // ============================================================================ @@ -73,12 +73,11 @@ private: private: mutable css::uno::WeakReference< ov::excel::XApplication > mxApplication; - ::rtl::Reference< ScVbaWindowListener > mxWindowListener; + ::rtl::Reference< ScVbaEventsListener > mxListener; ScDocShell* mpDocShell; ScDocument* mpDoc; ScRangeList maOldSelection; bool mbOpened; - bool mbClosed; }; // ============================================================================ diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index 525f108af..feeacc865 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -154,7 +154,6 @@ EXCEPTIONSFILES= \ $(SLO)$/formatsh.obj \ $(SLO)$/gridwin2.obj \ $(SLO)$/scextopt.obj \ - $(SLO)$/tabview3.obj \ $(SLO)$/tabvwshb.obj \ $(SLO)$/viewdata.obj \ $(SLO)$/viewfunc.obj \ diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index a004e8688..8ab17d51a 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 |