LCOV - code coverage report
Current view: top level - libreoffice/sc/source/ui/vba - vbaeventshelper.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 406 0.0 %
Date: 2012-12-27 Functions: 0 44 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "vbaeventshelper.hxx"
      21             : 
      22             : #include <com/sun/star/awt/XTopWindow.hpp>
      23             : #include <com/sun/star/awt/XTopWindowListener.hpp>
      24             : #include <com/sun/star/awt/XWindowListener.hpp>
      25             : #include <com/sun/star/frame/XBorderResizeListener.hpp>
      26             : #include <com/sun/star/frame/XControllerBorder.hpp>
      27             : #include <com/sun/star/script/ModuleType.hpp>
      28             : #include <com/sun/star/script/vba/VBAEventId.hpp>
      29             : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
      30             : #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
      31             : #include <com/sun/star/table/XCellRange.hpp>
      32             : #include <com/sun/star/util/XChangesListener.hpp>
      33             : #include <com/sun/star/util/XChangesNotifier.hpp>
      34             : 
      35             : #include <cppuhelper/implbase4.hxx>
      36             : #include <toolkit/unohlp.hxx>
      37             : #include <unotools/eventcfg.hxx>
      38             : #include <vbahelper/helperdecl.hxx>
      39             : #include <vcl/svapp.hxx>
      40             : #include <vcl/window.hxx>
      41             : 
      42             : #include "cellsuno.hxx"
      43             : #include "convuno.hxx"
      44             : #include "vbaapplication.hxx"
      45             : 
      46             : using namespace ::com::sun::star;
      47             : using namespace ::com::sun::star::script::vba::VBAEventId;
      48             : using namespace ::ooo::vba;
      49             : 
      50             : using ::rtl::OUString;
      51             : 
      52             : // ============================================================================
      53             : 
      54             : namespace {
      55             : 
      56             : /** Extracts a sheet index from the specified element of the passed sequence.
      57             :     The element may be an integer, a Calc range or ranges object, or a VBA Range object. */
      58           0 : SCTAB lclGetTabFromArgs( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException)
      59             : {
      60           0 :     VbaEventsHelperBase::checkArgument( rArgs, nIndex );
      61             : 
      62             :     // first try to extract a sheet index
      63           0 :     sal_Int32 nTab = -1;
      64           0 :     if( rArgs[ nIndex ] >>= nTab )
      65             :     {
      66           0 :         if( (nTab < 0) || (nTab > MAXTAB) )
      67           0 :             throw lang::IllegalArgumentException();
      68           0 :         return static_cast< SCTAB >( nTab );
      69             :     }
      70             : 
      71             :     // try VBA Range object
      72           0 :     uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
      73           0 :     if( xVbaRange.is() )
      74             :     {
      75           0 :         uno::Reference< XHelperInterface > xVbaHelper( xVbaRange, uno::UNO_QUERY_THROW );
      76             :         // TODO: in the future, the parent may be an excel::XChart (chart sheet) -> will there be a common base interface?
      77           0 :         uno::Reference< excel::XWorksheet > xVbaSheet( xVbaHelper->getParent(), uno::UNO_QUERY_THROW );
      78             :         // VBA sheet index is 1-based
      79           0 :         return static_cast< SCTAB >( xVbaSheet->getIndex() - 1 );
      80             :     }
      81             : 
      82             :     // try single UNO range object
      83           0 :     uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable = getXSomethingFromArgs< sheet::XCellRangeAddressable >( rArgs, nIndex );
      84           0 :     if( xCellRangeAddressable.is() )
      85           0 :         return xCellRangeAddressable->getRangeAddress().Sheet;
      86             : 
      87             :     // at last, try UNO range list
      88           0 :     uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
      89           0 :     if( xRanges.is() )
      90             :     {
      91           0 :         uno::Sequence< table::CellRangeAddress > aRangeAddresses = xRanges->getRangeAddresses();
      92           0 :         if( aRangeAddresses.getLength() > 0 )
      93           0 :             return aRangeAddresses[ 0 ].Sheet;
      94             :     }
      95             : 
      96           0 :     throw lang::IllegalArgumentException();
      97             : }
      98             : 
      99             : /** Returns the AWT container window of the passed controller. */
     100           0 : uno::Reference< awt::XWindow > lclGetWindowForController( const uno::Reference< frame::XController >& rxController )
     101             : {
     102           0 :     if( rxController.is() ) try
     103             :     {
     104           0 :         uno::Reference< frame::XFrame > xFrame( rxController->getFrame(), uno::UNO_SET_THROW );
     105           0 :         return xFrame->getContainerWindow();
     106             :     }
     107           0 :     catch( uno::Exception& )
     108             :     {
     109             :     }
     110           0 :     return 0;
     111             : }
     112             : 
     113             : } // namespace
     114             : 
     115             : // ============================================================================
     116             : 
     117             : typedef ::cppu::WeakImplHelper4< awt::XTopWindowListener, awt::XWindowListener, frame::XBorderResizeListener, util::XChangesListener > ScVbaEventListener_BASE;
     118             : 
     119             : // This class is to process Workbook window related event
     120             : class ScVbaEventListener : public ScVbaEventListener_BASE
     121             : {
     122             : public :
     123             :     ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell );
     124             :     virtual ~ScVbaEventListener();
     125             : 
     126             :     /** Starts listening to the passed document controller. */
     127             :     void startControllerListening( const uno::Reference< frame::XController >& rxController );
     128             :     /** Stops listening to the passed document controller. */
     129             :     void stopControllerListening( const uno::Reference< frame::XController >& rxController );
     130             : 
     131             :     // XTopWindowListener
     132             :     virtual void SAL_CALL windowOpened( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     133             :     virtual void SAL_CALL windowClosing( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     134             :     virtual void SAL_CALL windowClosed( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     135             :     virtual void SAL_CALL windowMinimized( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     136             :     virtual void SAL_CALL windowNormalized( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     137             :     virtual void SAL_CALL windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     138             :     virtual void SAL_CALL windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     139             : 
     140             :     // XWindowListener
     141             :     virtual void SAL_CALL windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException);
     142             :     virtual void SAL_CALL windowMoved( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException);
     143             :     virtual void SAL_CALL windowShown( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     144             :     virtual void SAL_CALL windowHidden( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     145             : 
     146             :     // XBorderResizeListener
     147             :     virtual void SAL_CALL borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& aNewSize ) throw (uno::RuntimeException);
     148             : 
     149             :     // XChangesListener
     150             :     virtual void SAL_CALL changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException);
     151             : 
     152             :     // XEventListener
     153             :     virtual void SAL_CALL disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException);
     154             : 
     155             : private:
     156             :     /** Starts listening to the document model. */
     157             :     void startModelListening();
     158             :     /** Stops listening to the document model. */
     159             :     void stopModelListening();
     160             : 
     161             :     /** Returns the controller for the passed VCL window. */
     162             :     uno::Reference< frame::XController > getControllerForWindow( Window* pWindow ) const;
     163             : 
     164             :     /** Calls the Workbook_Window[Activate|Deactivate] event handler. */
     165             :     void processWindowActivateEvent( Window* pWindow, bool bActivate );
     166             :     /** Posts a Workbook_WindowResize user event. */
     167             :     void postWindowResizeEvent( Window* pWindow );
     168             :     /** Callback link for Application::PostUserEvent(). */
     169             :     DECL_LINK( processWindowResizeEvent, Window* );
     170             : 
     171             : private:
     172             :     typedef ::std::map< Window*, uno::Reference< frame::XController > > WindowControllerMap;
     173             : 
     174             :     ::osl::Mutex        maMutex;
     175             :     ScVbaEventsHelper&  mrVbaEvents;
     176             :     uno::Reference< frame::XModel > mxModel;
     177             :     ScDocShell*         mpDocShell;
     178             :     WindowControllerMap maControllers;          /// Maps VCL top windows to their controllers.
     179             :     Window*             mpActiveWindow;         /// Currently activated window, to prevent multiple (de)activation.
     180             :     bool                mbWindowResized;        /// True = window resize system event processed.
     181             :     bool                mbBorderChanged;        /// True = borders changed system event processed.
     182             :     bool                mbDisposed;
     183             : };
     184             : 
     185             : // ----------------------------------------------------------------------------
     186             : 
     187           0 : ScVbaEventListener::ScVbaEventListener( ScVbaEventsHelper& rVbaEvents, const uno::Reference< frame::XModel >& rxModel, ScDocShell* pDocShell ) :
     188             :     mrVbaEvents( rVbaEvents ),
     189             :     mxModel( rxModel ),
     190             :     mpDocShell( pDocShell ),
     191             :     mpActiveWindow( 0 ),
     192             :     mbWindowResized( false ),
     193             :     mbBorderChanged( false ),
     194           0 :     mbDisposed( !rxModel.is() )
     195             : {
     196           0 :     if( !mxModel.is() )
     197           0 :         return;
     198             : 
     199           0 :     startModelListening();
     200             :     try
     201             :     {
     202           0 :         uno::Reference< frame::XController > xController( mxModel->getCurrentController(), uno::UNO_QUERY_THROW );
     203           0 :         startControllerListening( xController );
     204             :     }
     205           0 :     catch( uno::Exception& )
     206             :     {
     207             :     }
     208             : }
     209             : 
     210           0 : ScVbaEventListener::~ScVbaEventListener()
     211             : {
     212           0 : }
     213             : 
     214           0 : void ScVbaEventListener::startControllerListening( const uno::Reference< frame::XController >& rxController )
     215             : {
     216           0 :     ::osl::MutexGuard aGuard( maMutex );
     217             : 
     218           0 :     uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
     219           0 :     if( xWindow.is() )
     220           0 :         try { xWindow->addWindowListener( this ); } catch( uno::Exception& ) {}
     221             : 
     222           0 :     uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
     223           0 :     if( xTopWindow.is() )
     224           0 :         try { xTopWindow->addTopWindowListener( this ); } catch( uno::Exception& ) {}
     225             : 
     226           0 :     uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
     227           0 :     if( xControllerBorder.is() )
     228           0 :         try { xControllerBorder->addBorderResizeListener( this ); } catch( uno::Exception& ) {}
     229             : 
     230           0 :     if( Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) )
     231           0 :         maControllers[ pWindow ] = rxController;
     232           0 : }
     233             : 
     234           0 : void ScVbaEventListener::stopControllerListening( const uno::Reference< frame::XController >& rxController )
     235             : {
     236           0 :     ::osl::MutexGuard aGuard( maMutex );
     237             : 
     238           0 :     uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( rxController );
     239           0 :     if( xWindow.is() )
     240           0 :         try { xWindow->removeWindowListener( this ); } catch( uno::Exception& ) {}
     241             : 
     242           0 :     uno::Reference< awt::XTopWindow > xTopWindow( xWindow, uno::UNO_QUERY );
     243           0 :     if( xTopWindow.is() )
     244           0 :         try { xTopWindow->removeTopWindowListener( this ); } catch( uno::Exception& ) {}
     245             : 
     246           0 :     uno::Reference< frame::XControllerBorder > xControllerBorder( rxController, uno::UNO_QUERY );
     247           0 :     if( xControllerBorder.is() )
     248           0 :         try { xControllerBorder->removeBorderResizeListener( this ); } catch( uno::Exception& ) {}
     249             : 
     250           0 :     if( Window* pWindow = VCLUnoHelper::GetWindow( xWindow ) )
     251             :     {
     252           0 :         maControllers.erase( pWindow );
     253           0 :         if( pWindow == mpActiveWindow )
     254           0 :             mpActiveWindow = 0;
     255           0 :     }
     256           0 : }
     257             : 
     258           0 : void SAL_CALL ScVbaEventListener::windowOpened( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     259             : {
     260           0 : }
     261             : 
     262           0 : void SAL_CALL ScVbaEventListener::windowClosing( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     263             : {
     264           0 : }
     265             : 
     266           0 : void SAL_CALL ScVbaEventListener::windowClosed( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     267             : {
     268           0 : }
     269             : 
     270           0 : void SAL_CALL ScVbaEventListener::windowMinimized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     271             : {
     272           0 : }
     273             : 
     274           0 : void SAL_CALL ScVbaEventListener::windowNormalized( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     275             : {
     276           0 : }
     277             : 
     278           0 : void SAL_CALL ScVbaEventListener::windowActivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException)
     279             : {
     280           0 :     ::osl::MutexGuard aGuard( maMutex );
     281             : 
     282           0 :     if( !mbDisposed )
     283             :     {
     284           0 :         uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
     285           0 :         Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
     286             :         OSL_TRACE( "ScVbaEventListener::windowActivated - pWindow = 0x%x, mpActiveWindow = 0x%x", pWindow, mpActiveWindow );
     287             :         // do not fire activation event multiple time for the same window
     288           0 :         if( pWindow && (pWindow != mpActiveWindow) )
     289             :         {
     290             :             // if another window is active, fire deactivation event first
     291           0 :             if( mpActiveWindow )
     292           0 :                 processWindowActivateEvent( mpActiveWindow, false );
     293             :             // fire activation event for the new window
     294           0 :             processWindowActivateEvent( pWindow, true );
     295           0 :             mpActiveWindow = pWindow;
     296           0 :         }
     297           0 :     }
     298           0 : }
     299             : 
     300           0 : void SAL_CALL ScVbaEventListener::windowDeactivated( const lang::EventObject& rEvent ) throw (uno::RuntimeException)
     301             : {
     302           0 :     ::osl::MutexGuard aGuard( maMutex );
     303             : 
     304           0 :     if( !mbDisposed )
     305             :     {
     306           0 :         uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
     307           0 :         Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
     308             :         OSL_TRACE( "ScVbaEventListener::windowDeactivated - pWindow = 0x%x, mpActiveWindow = 0x%x", pWindow, mpActiveWindow );
     309             :         // do not fire the deactivation event, if the window is not active (prevent multiple deactivation)
     310           0 :         if( pWindow && (pWindow == mpActiveWindow) )
     311           0 :             processWindowActivateEvent( pWindow, false );
     312             :         // forget pointer to the active window
     313           0 :         mpActiveWindow = 0;
     314           0 :     }
     315           0 : }
     316             : 
     317           0 : void SAL_CALL ScVbaEventListener::windowResized( const awt::WindowEvent& rEvent ) throw (uno::RuntimeException)
     318             : {
     319           0 :     ::osl::MutexGuard aGuard( maMutex );
     320             : 
     321           0 :     mbWindowResized = true;
     322           0 :     if( !mbDisposed && mbBorderChanged )
     323             :     {
     324           0 :         uno::Reference< awt::XWindow > xWindow( rEvent.Source, uno::UNO_QUERY );
     325           0 :         postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
     326           0 :     }
     327           0 : }
     328             : 
     329           0 : void SAL_CALL ScVbaEventListener::windowMoved( const awt::WindowEvent& /*rEvent*/ ) throw (uno::RuntimeException)
     330             : {
     331           0 : }
     332             : 
     333           0 : void SAL_CALL ScVbaEventListener::windowShown( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     334             : {
     335           0 : }
     336             : 
     337           0 : void SAL_CALL ScVbaEventListener::windowHidden( const lang::EventObject& /*rEvent*/ ) throw (uno::RuntimeException)
     338             : {
     339           0 : }
     340             : 
     341           0 : void SAL_CALL ScVbaEventListener::borderWidthsChanged( const uno::Reference< uno::XInterface >& rSource, const frame::BorderWidths& /*aNewSize*/ ) throw (uno::RuntimeException)
     342             : {
     343           0 :     ::osl::MutexGuard aGuard( maMutex );
     344             : 
     345           0 :     mbBorderChanged = true;
     346           0 :     if( !mbDisposed && mbWindowResized )
     347             :     {
     348           0 :         uno::Reference< frame::XController > xController( rSource, uno::UNO_QUERY );
     349           0 :         uno::Reference< awt::XWindow > xWindow = lclGetWindowForController( xController );
     350           0 :         postWindowResizeEvent( VCLUnoHelper::GetWindow( xWindow ) );
     351           0 :     }
     352           0 : }
     353             : 
     354           0 : void SAL_CALL ScVbaEventListener::changesOccurred( const util::ChangesEvent& rEvent ) throw (uno::RuntimeException)
     355             : {
     356           0 :     ::osl::MutexGuard aGuard( maMutex );
     357             : 
     358           0 :     sal_Int32 nCount = rEvent.Changes.getLength();
     359           0 :     if( mbDisposed || !mpDocShell || (nCount == 0) )
     360             :         return;
     361             : 
     362           0 :     util::ElementChange aChange = rEvent.Changes[ 0 ];
     363           0 :     OUString sOperation;
     364           0 :     aChange.Accessor >>= sOperation;
     365           0 :     if( !sOperation.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("cell-change")) )
     366             :         return;
     367             : 
     368           0 :     if( nCount == 1 )
     369             :     {
     370           0 :         uno::Reference< table::XCellRange > xRangeObj;
     371           0 :         aChange.ReplacedElement >>= xRangeObj;
     372           0 :         if( xRangeObj.is() )
     373             :         {
     374           0 :             uno::Sequence< uno::Any > aArgs( 1 );
     375           0 :             aArgs[0] <<= xRangeObj;
     376           0 :             mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
     377             :         }
     378           0 :         return;
     379             :     }
     380             : 
     381           0 :     ScRangeList aRangeList;
     382           0 :     for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex )
     383             :     {
     384           0 :         aChange = rEvent.Changes[ nIndex ];
     385           0 :         aChange.Accessor >>= sOperation;
     386           0 :         uno::Reference< table::XCellRange > xRangeObj;
     387           0 :         aChange.ReplacedElement >>= xRangeObj;
     388           0 :         if( xRangeObj.is() && sOperation.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("cell-change")) )
     389             :         {
     390           0 :             uno::Reference< sheet::XCellRangeAddressable > xCellRangeAddressable( xRangeObj, uno::UNO_QUERY );
     391           0 :             if( xCellRangeAddressable.is() )
     392             :             {
     393           0 :                 ScRange aRange;
     394           0 :                 ScUnoConversion::FillScRange( aRange, xCellRangeAddressable->getRangeAddress() );
     395           0 :                 aRangeList.Append( aRange );
     396           0 :             }
     397             :         }
     398           0 :     }
     399             : 
     400           0 :     if (!aRangeList.empty())
     401             :     {
     402           0 :         uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( mpDocShell, aRangeList ) );
     403           0 :         uno::Sequence< uno::Any > aArgs(1);
     404           0 :         aArgs[0] <<= xRanges;
     405           0 :         mrVbaEvents.processVbaEventNoThrow( WORKSHEET_CHANGE, aArgs );
     406           0 :     }
     407             : }
     408             : 
     409           0 : void SAL_CALL ScVbaEventListener::disposing( const lang::EventObject& rEvent ) throw (uno::RuntimeException)
     410             : {
     411           0 :     ::osl::MutexGuard aGuard( maMutex );
     412             : 
     413           0 :     uno::Reference< frame::XModel > xModel( rEvent.Source, uno::UNO_QUERY );
     414           0 :     if( xModel.is() )
     415             :     {
     416             :         OSL_ENSURE( xModel.get() == mxModel.get(), "ScVbaEventListener::disposing - disposing from unknown model" );
     417           0 :         stopModelListening();
     418           0 :         mbDisposed = true;
     419             :         return;
     420             :     }
     421             : 
     422           0 :     uno::Reference< frame::XController > xController( rEvent.Source, uno::UNO_QUERY );
     423           0 :     if( xController.is() )
     424             :     {
     425           0 :         stopControllerListening( xController );
     426             :         return;
     427           0 :     }
     428             : }
     429             : 
     430             : // private --------------------------------------------------------------------
     431             : 
     432           0 : void ScVbaEventListener::startModelListening()
     433             : {
     434             :     try
     435             :     {
     436           0 :         uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
     437           0 :         xChangesNotifier->addChangesListener( this );
     438             :     }
     439           0 :     catch( uno::Exception& )
     440             :     {
     441             :     }
     442           0 : }
     443             : 
     444           0 : void ScVbaEventListener::stopModelListening()
     445             : {
     446             :     try
     447             :     {
     448           0 :         uno::Reference< util::XChangesNotifier > xChangesNotifier( mxModel, uno::UNO_QUERY_THROW );
     449           0 :         xChangesNotifier->removeChangesListener( this );
     450             :     }
     451           0 :     catch( uno::Exception& )
     452             :     {
     453             :     }
     454           0 : }
     455             : 
     456           0 : uno::Reference< frame::XController > ScVbaEventListener::getControllerForWindow( Window* pWindow ) const
     457             : {
     458           0 :     WindowControllerMap::const_iterator aIt = maControllers.find( pWindow );
     459           0 :     return (aIt == maControllers.end()) ? uno::Reference< frame::XController >() : aIt->second;
     460             : }
     461             : 
     462           0 : void ScVbaEventListener::processWindowActivateEvent( Window* pWindow, bool bActivate )
     463             : {
     464           0 :     uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
     465           0 :     if( xController.is() )
     466             :     {
     467           0 :         uno::Sequence< uno::Any > aArgs( 1 );
     468           0 :         aArgs[ 0 ] <<= xController;
     469           0 :         mrVbaEvents.processVbaEventNoThrow( bActivate ? WORKBOOK_WINDOWACTIVATE : WORKBOOK_WINDOWDEACTIVATE, aArgs );
     470           0 :     }
     471           0 : }
     472             : 
     473           0 : void ScVbaEventListener::postWindowResizeEvent( Window* pWindow )
     474             : {
     475             :     // check that the passed window is still alive (it must be registered in maControllers)
     476           0 :     if( pWindow && (maControllers.count( pWindow ) > 0) )
     477             :     {
     478           0 :         mbWindowResized = mbBorderChanged = false;
     479           0 :         acquire();  // ensure we don't get deleted before the timer fires
     480           0 :         Application::PostUserEvent( LINK( this, ScVbaEventListener, processWindowResizeEvent ), pWindow );
     481             :     }
     482           0 : }
     483             : 
     484           0 : IMPL_LINK( ScVbaEventListener, processWindowResizeEvent, Window*, EMPTYARG pWindow )
     485             : {
     486           0 :     ::osl::MutexGuard aGuard( maMutex );
     487             : 
     488             :     /*  Check that the passed window is still alive (it must be registered in
     489             :         maControllers). While closing a document, postWindowResizeEvent() may
     490             :         be called on the last window which posts a user event via
     491             :         Application::PostUserEvent to call this event handler. VCL will trigger
     492             :         the handler some time later. Sometimes, the window gets deleted before.
     493             :         This is handled via the disposing() function which removes the window
     494             :         pointer from the member maControllers. Thus, checking whether
     495             :         maControllers contains pWindow ensures that the window is still alive. */
     496           0 :     if( !mbDisposed && pWindow && (maControllers.count( pWindow ) > 0) )
     497             :     {
     498             :         // do not fire event unless all mouse buttons have been released
     499           0 :         Window::PointerState aPointerState = pWindow->GetPointerState();
     500           0 :         if( (aPointerState.mnState & (MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT)) == 0 )
     501             :         {
     502           0 :             uno::Reference< frame::XController > xController = getControllerForWindow( pWindow );
     503           0 :             if( xController.is() )
     504             :             {
     505           0 :                 uno::Sequence< uno::Any > aArgs( 1 );
     506           0 :                 aArgs[ 0 ] <<= xController;
     507             :                 // #163419# do not throw exceptions into application core
     508           0 :                 mrVbaEvents.processVbaEventNoThrow( WORKBOOK_WINDOWRESIZE, aArgs );
     509           0 :             }
     510             :         }
     511             :     }
     512           0 :     release();
     513           0 :     return 0;
     514             : }
     515             : 
     516             : // ============================================================================
     517             : 
     518           0 : ScVbaEventsHelper::ScVbaEventsHelper( const uno::Sequence< uno::Any >& rArgs, const uno::Reference< uno::XComponentContext >& xContext ) :
     519             :     VbaEventsHelperBase( rArgs, xContext ),
     520           0 :     mbOpened( false )
     521             : {
     522           0 :     mpDocShell = dynamic_cast< ScDocShell* >( mpShell ); // mpShell from base class
     523           0 :     mpDoc = mpDocShell ? mpDocShell->GetDocument() : 0;
     524             : 
     525           0 :     if( !mxModel.is() || !mpDocShell || !mpDoc )
     526           0 :         return;
     527             : 
     528             : #define REGISTER_EVENT( eventid, moduletype, classname, eventname, cancelindex, worksheet ) \
     529             :     registerEventHandler( eventid, moduletype, classname "_" eventname, cancelindex, uno::Any( worksheet ) )
     530             : #define REGISTER_AUTO_EVENT( eventid, eventname ) \
     531             :     REGISTER_EVENT( AUTO_##eventid, script::ModuleType::NORMAL, "Auto", eventname, -1, false )
     532             : #define REGISTER_WORKBOOK_EVENT( eventid, eventname, cancelindex ) \
     533             :     REGISTER_EVENT( WORKBOOK_##eventid, script::ModuleType::DOCUMENT, "Workbook", eventname, cancelindex, false )
     534             : #define REGISTER_WORKSHEET_EVENT( eventid, eventname, cancelindex ) \
     535             :     REGISTER_EVENT( WORKSHEET_##eventid, script::ModuleType::DOCUMENT, "Worksheet", eventname, cancelindex, true ); \
     536             :     REGISTER_EVENT( (USERDEFINED_START + WORKSHEET_##eventid), script::ModuleType::DOCUMENT, "Workbook", "Sheet" eventname, (((cancelindex) >= 0) ? ((cancelindex) + 1) : -1), false )
     537             : 
     538             :     // global
     539           0 :     REGISTER_AUTO_EVENT( OPEN,  "Open" );
     540           0 :     REGISTER_AUTO_EVENT( CLOSE, "Close" );
     541             : 
     542             :     // Workbook
     543           0 :     REGISTER_WORKBOOK_EVENT( ACTIVATE,            "Activate",           -1 );
     544           0 :     REGISTER_WORKBOOK_EVENT( DEACTIVATE,          "Deactivate",         -1 );
     545           0 :     REGISTER_WORKBOOK_EVENT( OPEN,                "Open",               -1 );
     546           0 :     REGISTER_WORKBOOK_EVENT( BEFORECLOSE,         "BeforeClose",        0 );
     547           0 :     REGISTER_WORKBOOK_EVENT( BEFOREPRINT,         "BeforePrint",        0 );
     548           0 :     REGISTER_WORKBOOK_EVENT( BEFORESAVE,          "BeforeSave",         1 );
     549           0 :     REGISTER_WORKBOOK_EVENT( AFTERSAVE,           "AfterSave",          -1 );
     550           0 :     REGISTER_WORKBOOK_EVENT( NEWSHEET,            "NewSheet",           -1 );
     551           0 :     REGISTER_WORKBOOK_EVENT( WINDOWACTIVATE,      "WindowActivate",     -1 );
     552           0 :     REGISTER_WORKBOOK_EVENT( WINDOWDEACTIVATE,    "WindowDeactivate",   -1 );
     553           0 :     REGISTER_WORKBOOK_EVENT( WINDOWRESIZE,        "WindowResize",       -1 );
     554             : 
     555             :     // Worksheet events. All events have a corresponding workbook event.
     556           0 :     REGISTER_WORKSHEET_EVENT( ACTIVATE,           "Activate",           -1 );
     557           0 :     REGISTER_WORKSHEET_EVENT( DEACTIVATE,         "Deactivate",         -1 );
     558           0 :     REGISTER_WORKSHEET_EVENT( BEFOREDOUBLECLICK,  "BeforeDoubleClick",  1 );
     559           0 :     REGISTER_WORKSHEET_EVENT( BEFORERIGHTCLICK,   "BeforeRightClick",   1 );
     560           0 :     REGISTER_WORKSHEET_EVENT( CALCULATE,          "Calculate",          -1 );
     561           0 :     REGISTER_WORKSHEET_EVENT( CHANGE,             "Change",             -1 );
     562           0 :     REGISTER_WORKSHEET_EVENT( SELECTIONCHANGE,    "SelectionChange",    -1 );
     563           0 :     REGISTER_WORKSHEET_EVENT( FOLLOWHYPERLINK,    "FollowHyperlink",    -1 );
     564             : 
     565             : #undef REGISTER_WORKSHEET_EVENT
     566             : #undef REGISTER_WORKBOOK_EVENT
     567             : #undef REGISTER_AUTO_EVENT
     568             : #undef REGISTER_EVENT
     569             : }
     570             : 
     571           0 : ScVbaEventsHelper::~ScVbaEventsHelper()
     572             : {
     573           0 : }
     574             : 
     575           0 : void SAL_CALL ScVbaEventsHelper::notifyEvent( const css::document::EventObject& rEvent ) throw (css::uno::RuntimeException)
     576             : {
     577           0 :     static const uno::Sequence< uno::Any > saEmptyArgs;
     578           0 :     if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_OPENDOC )) ||
     579           0 :         (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CREATEDOC )) )  // CREATEDOC triggered e.g. during VBA Workbooks.Add
     580             :     {
     581           0 :         processVbaEventNoThrow( WORKBOOK_OPEN, saEmptyArgs );
     582             :     }
     583           0 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_ACTIVATEDOC ) )
     584             :     {
     585           0 :         processVbaEventNoThrow( WORKBOOK_ACTIVATE, saEmptyArgs );
     586             :     }
     587           0 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_DEACTIVATEDOC ) )
     588             :     {
     589           0 :         processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
     590             :     }
     591           0 :     else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCDONE )) ||
     592           0 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCDONE )) ||
     593           0 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCDONE )) )
     594             :     {
     595           0 :         uno::Sequence< uno::Any > aArgs( 1 );
     596           0 :         aArgs[ 0 ] <<= true;
     597           0 :         processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
     598             :     }
     599           0 :     else if( (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEDOCFAILED )) ||
     600           0 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVEASDOCFAILED )) ||
     601           0 :              (rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_SAVETODOCFAILED )) )
     602             :     {
     603           0 :         uno::Sequence< uno::Any > aArgs( 1 );
     604           0 :         aArgs[ 0 ] <<= false;
     605           0 :         processVbaEventNoThrow( WORKBOOK_AFTERSAVE, aArgs );
     606             :     }
     607           0 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_CLOSEDOC ) )
     608             :     {
     609             :         /*  Trigger the WORKBOOK_WINDOWDEACTIVATE and WORKBOOK_DEACTIVATE
     610             :             events and stop listening to the model (done in base class). */
     611           0 :         uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
     612           0 :         if( xController.is() )
     613             :         {
     614           0 :             uno::Sequence< uno::Any > aArgs( 1 );
     615           0 :             aArgs[ 0 ] <<= xController;
     616           0 :             processVbaEventNoThrow( WORKBOOK_WINDOWDEACTIVATE, aArgs );
     617             :         }
     618           0 :         processVbaEventNoThrow( WORKBOOK_DEACTIVATE, saEmptyArgs );
     619             :     }
     620           0 :     else if( rEvent.EventName == GlobalEventConfig::GetEventName( STR_EVENT_VIEWCREATED ) )
     621             :     {
     622           0 :         uno::Reference< frame::XController > xController( mxModel->getCurrentController() );
     623           0 :         if( mxListener.get() && xController.is() )
     624           0 :             mxListener->startControllerListening( xController );
     625             :     }
     626           0 :     VbaEventsHelperBase::notifyEvent( rEvent );
     627           0 : }
     628             : 
     629             : // protected ------------------------------------------------------------------
     630             : 
     631           0 : bool ScVbaEventsHelper::implPrepareEvent( EventQueue& rEventQueue,
     632             :         const EventHandlerInfo& rInfo, const uno::Sequence< uno::Any >& rArgs ) throw (uno::RuntimeException)
     633             : {
     634             :     // document and document shell are needed during event processing
     635           0 :     if( !mpShell || !mpDoc )
     636           0 :         throw uno::RuntimeException();
     637             : 
     638             :     /*  For document events: check if events are enabled via the
     639             :         Application.EnableEvents symbol (this is an Excel-only attribute).
     640             :         Check this again for every event, as the event handler may change the
     641             :         state of the EnableEvents symbol. Global events such as AUTO_OPEN and
     642             :         AUTO_CLOSE are always enabled. */
     643           0 :     bool bExecuteEvent = (rInfo.mnModuleType != script::ModuleType::DOCUMENT) || ScVbaApplication::getDocumentEventsEnabled();
     644             : 
     645             :     // framework and Calc fire a few events before 'OnLoad', ignore them
     646           0 :     if( bExecuteEvent )
     647           0 :         bExecuteEvent = (rInfo.mnEventId == WORKBOOK_OPEN) ? !mbOpened : mbOpened;
     648             : 
     649             :     // special handling for some events
     650           0 :     if( bExecuteEvent ) switch( rInfo.mnEventId )
     651             :     {
     652             :         case WORKBOOK_OPEN:
     653             :         {
     654             :             // execute delayed Activate event too (see above)
     655           0 :             rEventQueue.push_back( WORKBOOK_ACTIVATE );
     656           0 :             uno::Sequence< uno::Any > aArgs( 1 );
     657           0 :             aArgs[ 0 ] <<= mxModel->getCurrentController();
     658           0 :             rEventQueue.push_back( EventQueueEntry( WORKBOOK_WINDOWACTIVATE, aArgs ) );
     659           0 :             rEventQueue.push_back( AUTO_OPEN );
     660             :             // remember initial selection
     661           0 :             maOldSelection <<= mxModel->getCurrentSelection();
     662             :         }
     663           0 :         break;
     664             :         case WORKSHEET_SELECTIONCHANGE:
     665             :             // if selection is not changed, then do not fire the event
     666           0 :             bExecuteEvent = isSelectionChanged( rArgs, 0 );
     667           0 :         break;
     668             :     }
     669             : 
     670           0 :     if( bExecuteEvent )
     671             :     {
     672             :         // add workbook event associated to a sheet event
     673           0 :         bool bSheetEvent = false;
     674           0 :         if( (rInfo.maUserData >>= bSheetEvent) && bSheetEvent )
     675           0 :             rEventQueue.push_back( EventQueueEntry( rInfo.mnEventId + USERDEFINED_START, rArgs ) );
     676             :     }
     677             : 
     678           0 :     return bExecuteEvent;
     679             : }
     680             : 
     681           0 : uno::Sequence< uno::Any > ScVbaEventsHelper::implBuildArgumentList( const EventHandlerInfo& rInfo,
     682             :         const uno::Sequence< uno::Any >& rArgs ) throw (lang::IllegalArgumentException)
     683             : {
     684             :     // fill arguments for workbook events associated to sheet events according to sheet events, sheet will be added below
     685           0 :     bool bSheetEventAsBookEvent = rInfo.mnEventId > USERDEFINED_START;
     686           0 :     sal_Int32 nEventId = bSheetEventAsBookEvent ? (rInfo.mnEventId - USERDEFINED_START) : rInfo.mnEventId;
     687             : 
     688           0 :     uno::Sequence< uno::Any > aVbaArgs;
     689           0 :     switch( nEventId )
     690             :     {
     691             :         // *** Workbook ***
     692             : 
     693             :         // no arguments
     694             :         case WORKBOOK_ACTIVATE:
     695             :         case WORKBOOK_DEACTIVATE:
     696             :         case WORKBOOK_OPEN:
     697           0 :         break;
     698             :         // 1 arg: cancel
     699             :         case WORKBOOK_BEFORECLOSE:
     700             :         case WORKBOOK_BEFOREPRINT:
     701           0 :             aVbaArgs.realloc( 1 );
     702             :             // current cancel state will be inserted by caller
     703           0 :         break;
     704             :         // 2 args: saveAs, cancel
     705             :         case WORKBOOK_BEFORESAVE:
     706           0 :             aVbaArgs.realloc( 2 );
     707           0 :             checkArgumentType< bool >( rArgs, 0 );
     708           0 :             aVbaArgs[ 0 ] = rArgs[ 0 ];
     709             :             // current cancel state will be inserted by caller
     710           0 :         break;
     711             :         // 1 arg: success
     712             :         case WORKBOOK_AFTERSAVE:
     713           0 :             aVbaArgs.realloc( 1 );
     714           0 :             checkArgumentType< bool >( rArgs, 0 );
     715           0 :             aVbaArgs[ 0 ] = rArgs[ 0 ];
     716           0 :         break;
     717             :         // 1 arg: window
     718             :         case WORKBOOK_WINDOWACTIVATE:
     719             :         case WORKBOOK_WINDOWDEACTIVATE:
     720             :         case WORKBOOK_WINDOWRESIZE:
     721           0 :             aVbaArgs.realloc( 1 );
     722           0 :             aVbaArgs[ 0 ] = createWindow( rArgs, 0 );
     723           0 :         break;
     724             :         // 1 arg: worksheet
     725             :         case WORKBOOK_NEWSHEET:
     726           0 :             aVbaArgs.realloc( 1 );
     727           0 :             aVbaArgs[ 0 ] = createWorksheet( rArgs, 0 );
     728           0 :         break;
     729             : 
     730             :         // *** Worksheet ***
     731             : 
     732             :         // no arguments
     733             :         case WORKSHEET_ACTIVATE:
     734             :         case WORKSHEET_CALCULATE:
     735             :         case WORKSHEET_DEACTIVATE:
     736           0 :         break;
     737             :         // 1 arg: range
     738             :         case WORKSHEET_CHANGE:
     739             :         case WORKSHEET_SELECTIONCHANGE:
     740           0 :             aVbaArgs.realloc( 1 );
     741           0 :             aVbaArgs[ 0 ] = createRange( rArgs, 0 );
     742           0 :         break;
     743             :         // 2 args: range, cancel
     744             :         case WORKSHEET_BEFOREDOUBLECLICK:
     745             :         case WORKSHEET_BEFORERIGHTCLICK:
     746           0 :             aVbaArgs.realloc( 2 );
     747           0 :             aVbaArgs[ 0 ] = createRange( rArgs, 0 );
     748             :             // current cancel state will be inserted by caller
     749           0 :         break;
     750             :         // 1 arg: hyperlink
     751             :         case WORKSHEET_FOLLOWHYPERLINK:
     752           0 :             aVbaArgs.realloc( 1 );
     753           0 :             aVbaArgs[ 0 ] = createHyperlink( rArgs, 0 );
     754           0 :         break;
     755             :     }
     756             : 
     757             :     /*  For workbook events associated to sheet events, the workbook event gets
     758             :         the same arguments but with a Worksheet object in front of them. */
     759           0 :     if( bSheetEventAsBookEvent )
     760             :     {
     761           0 :         sal_Int32 nLength = aVbaArgs.getLength();
     762           0 :         uno::Sequence< uno::Any > aVbaArgs2( nLength + 1 );
     763           0 :         aVbaArgs2[ 0 ] = createWorksheet( rArgs, 0 );
     764           0 :         for( sal_Int32 nIndex = 0; nIndex < nLength; ++nIndex )
     765           0 :             aVbaArgs2[ nIndex + 1 ] = aVbaArgs[ nIndex ];
     766           0 :         aVbaArgs = aVbaArgs2;
     767             :     }
     768             : 
     769           0 :     return aVbaArgs;
     770             : }
     771             : 
     772           0 : void ScVbaEventsHelper::implPostProcessEvent( EventQueue& rEventQueue,
     773             :         const EventHandlerInfo& rInfo, bool bCancel ) throw (uno::RuntimeException)
     774             : {
     775           0 :     switch( rInfo.mnEventId )
     776             :     {
     777             :         case WORKBOOK_OPEN:
     778           0 :             mbOpened = true;
     779             :             // register the listeners
     780           0 :             if( !mxListener.is() )
     781           0 :                 mxListener = new ScVbaEventListener( *this, mxModel, mpDocShell );
     782           0 :         break;
     783             :         case WORKBOOK_BEFORECLOSE:
     784             :             /*  Execute Auto_Close only if not cancelled by event handler, but
     785             :                 before UI asks user whether to cancel closing the document. */
     786           0 :             if( !bCancel )
     787           0 :                 rEventQueue.push_back( AUTO_CLOSE );
     788           0 :         break;
     789             :     }
     790           0 : }
     791             : 
     792           0 : OUString ScVbaEventsHelper::implGetDocumentModuleName( const EventHandlerInfo& rInfo,
     793             :         const uno::Sequence< uno::Any >& rArgs ) const throw (lang::IllegalArgumentException)
     794             : {
     795           0 :     bool bSheetEvent = false;
     796           0 :     rInfo.maUserData >>= bSheetEvent;
     797           0 :     SCTAB nTab = bSheetEvent ? lclGetTabFromArgs( rArgs, 0 ) : -1;
     798           0 :     if( bSheetEvent && (nTab < 0) )
     799           0 :         throw lang::IllegalArgumentException();
     800             : 
     801           0 :     rtl::OUString aCodeName;
     802           0 :     if( bSheetEvent )
     803           0 :         mpDoc->GetCodeName( nTab, aCodeName );
     804             :     else
     805           0 :         aCodeName = mpDoc->GetCodeName();
     806           0 :     return aCodeName;
     807             : }
     808             : 
     809             : // private --------------------------------------------------------------------
     810             : 
     811             : namespace {
     812             : 
     813             : /** Compares the passed range lists representing sheet selections. Ignores
     814             :     selections that refer to different sheets (returns false in this case). */
     815           0 : bool lclSelectionChanged( const ScRangeList& rLeft, const ScRangeList& rRight )
     816             : {
     817             :     // one of the range lists empty? -> return false, if both lists empty
     818           0 :     bool bLeftEmpty = rLeft.empty();
     819           0 :     bool bRightEmpty = rRight.empty();
     820           0 :     if( bLeftEmpty || bRightEmpty )
     821           0 :         return !(bLeftEmpty && bRightEmpty);
     822             : 
     823             :     // check sheet indexes of the range lists (assuming that all ranges in a list are on the same sheet)
     824           0 :     if (rLeft[0]->aStart.Tab() != rRight[0]->aStart.Tab())
     825           0 :         return false;
     826             : 
     827             :     // compare all ranges
     828           0 :     return rLeft != rRight;
     829             : }
     830             : 
     831             : } // namespace
     832             : 
     833           0 : bool ScVbaEventsHelper::isSelectionChanged( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     834             : {
     835           0 :     uno::Reference< uno::XInterface > xOldSelection( maOldSelection, uno::UNO_QUERY );
     836           0 :     uno::Reference< uno::XInterface > xNewSelection = getXSomethingFromArgs< uno::XInterface >( rArgs, nIndex, false );
     837           0 :     ScCellRangesBase* pOldCellRanges = ScCellRangesBase::getImplementation( xOldSelection );
     838           0 :     ScCellRangesBase* pNewCellRanges = ScCellRangesBase::getImplementation( xNewSelection );
     839           0 :     bool bChanged = !pOldCellRanges || !pNewCellRanges || lclSelectionChanged( pOldCellRanges->GetRangeList(), pNewCellRanges->GetRangeList() );
     840           0 :     maOldSelection <<= xNewSelection;
     841           0 :     return bChanged;
     842             : }
     843             : 
     844           0 : uno::Any ScVbaEventsHelper::createWorksheet( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     845             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     846             : {
     847             :     // extract sheet index, will throw, if parameter is invalid
     848           0 :     SCTAB nTab = lclGetTabFromArgs( rArgs, nIndex );
     849           0 :     return uno::Any( excel::getUnoSheetModuleObj( mxModel, nTab ) );
     850             : }
     851             : 
     852           0 : uno::Any ScVbaEventsHelper::createRange( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     853             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     854             : {
     855             :     // it is possible to pass an existing VBA Range object
     856           0 :     uno::Reference< excel::XRange > xVbaRange = getXSomethingFromArgs< excel::XRange >( rArgs, nIndex );
     857           0 :     if( !xVbaRange.is() )
     858             :     {
     859           0 :         uno::Reference< sheet::XSheetCellRangeContainer > xRanges = getXSomethingFromArgs< sheet::XSheetCellRangeContainer >( rArgs, nIndex );
     860           0 :         uno::Reference< table::XCellRange > xRange = getXSomethingFromArgs< table::XCellRange >( rArgs, nIndex );
     861           0 :         if ( !xRanges.is() && !xRange.is() )
     862           0 :             throw lang::IllegalArgumentException();
     863             : 
     864           0 :         uno::Sequence< uno::Any > aArgs( 2 );
     865           0 :         if ( xRanges.is() )
     866             :         {
     867           0 :             aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRanges );
     868           0 :             aArgs[ 1 ] <<= xRanges;
     869             :         }
     870             :         else
     871             :         {
     872           0 :             aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xRange );
     873           0 :             aArgs[ 1 ] <<= xRange;
     874             :         }
     875           0 :         xVbaRange.set( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Range", aArgs ), uno::UNO_QUERY_THROW );
     876             :     }
     877           0 :     return uno::Any( xVbaRange );
     878             : }
     879             : 
     880           0 : uno::Any ScVbaEventsHelper::createHyperlink( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     881             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     882             : {
     883           0 :     uno::Reference< table::XCell > xCell = getXSomethingFromArgs< table::XCell >( rArgs, nIndex, false );
     884           0 :     uno::Sequence< uno::Any > aArgs( 2 );
     885           0 :     aArgs[ 0 ] <<= excel::getUnoSheetModuleObj( xCell );
     886           0 :     aArgs[ 1 ] <<= xCell;
     887           0 :     uno::Reference< uno::XInterface > xHyperlink( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Hyperlink", aArgs ), uno::UNO_SET_THROW );
     888           0 :     return uno::Any( xHyperlink );
     889             : }
     890             : 
     891           0 : uno::Any ScVbaEventsHelper::createWindow( const uno::Sequence< uno::Any >& rArgs, sal_Int32 nIndex ) const
     892             :         throw (lang::IllegalArgumentException, uno::RuntimeException)
     893             : {
     894           0 :     uno::Sequence< uno::Any > aArgs( 3 );
     895           0 :     aArgs[ 0 ] <<= getVBADocument( mxModel );
     896           0 :     aArgs[ 1 ] <<= mxModel;
     897           0 :     aArgs[ 2 ] <<= getXSomethingFromArgs< frame::XController >( rArgs, nIndex, false );
     898           0 :     uno::Reference< uno::XInterface > xWindow( createVBAUnoAPIServiceWithArgs( mpShell, "ooo.vba.excel.Window", aArgs ), uno::UNO_SET_THROW );
     899           0 :     return uno::Any( xWindow );
     900             : }
     901             : 
     902             : // ============================================================================
     903             : 
     904             : namespace vbaeventshelper
     905             : {
     906             : namespace sdecl = comphelper::service_decl;
     907           0 : sdecl::class_<ScVbaEventsHelper, sdecl::with_args<true> > serviceImpl;
     908           0 : extern sdecl::ServiceDecl const serviceDecl(
     909             :     serviceImpl,
     910             :     "ScVbaEventsHelper",
     911             :     "com.sun.star.script.vba.VBASpreadsheetEventProcessor" );
     912           0 : }
     913             : 
     914             : // ============================================================================
     915             : 
     916             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10