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

Generated by: LCOV version 1.10